feat: implement self-hosted scripts and agent binary proxy with tar.gz conversion

This commit is contained in:
Bot
2026-05-11 17:39:37 +08:00
parent 3319d7344f
commit 3d00f09493
7 changed files with 640 additions and 3 deletions
+3 -1
View File
@@ -60,6 +60,9 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
api.POST("/login", authMiddleware.LoginHandler) api.POST("/login", authMiddleware.LoginHandler)
api.GET("/oauth2/:provider", commonHandler(oauth2redirect)) api.GET("/oauth2/:provider", commonHandler(oauth2redirect))
r.GET("/script/:name", serveScript)
r.GET("/script/bin/:os/:arch", serveAgentBinary)
fallbackAuthMw := fallbackAuthMiddleware(authMiddleware) fallbackAuthMw := fallbackAuthMiddleware(authMiddleware)
fallbackAuth := api.Group("", fallbackAuthMw) fallbackAuth := api.Group("", fallbackAuthMw)
fallbackAuth.GET("/setting", commonHandler(listConfig)) fallbackAuth.GET("/setting", commonHandler(listConfig))
@@ -83,7 +86,6 @@ func routers(r *gin.Engine, frontendDist fs.FS) {
auth.GET("/refresh-token", authMiddleware.RefreshHandler) auth.GET("/refresh-token", authMiddleware.RefreshHandler)
auth.GET("/file", commonHandler(createFM)) auth.GET("/file", commonHandler(createFM))
auth.GET("/ws/file/:id", commonHandler(fmStream)) auth.GET("/ws/file/:id", commonHandler(fmStream))
+121
View File
@@ -0,0 +1,121 @@
package controller
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"embed"
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"github.com/gin-gonic/gin"
)
//go:embed scripts/*
var scriptFS embed.FS
func serveScript(c *gin.Context) {
name := c.Param("name")
content, err := scriptFS.ReadFile(filepath.Join("scripts", name))
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Script not found"})
return
}
c.Data(http.StatusOK, "text/plain; charset=utf-8", content)
}
func serveAgentBinary(c *gin.Context) {
osType := c.Param("os")
arch := c.Param("arch")
// Nezha agent releases are usually .zip
// We will proxy the download from GitHub/Gitee and convert it to .tar.gz on the fly
// This allows using 'tar' in the install script and avoids GitHub connectivity issues
repo := "nezhahq/agent"
// For simplicity, we use the latest release
// In a real scenario, you might want to cache this or use a specific version
zipUrl := fmt.Sprintf("https://github.com/%s/releases/latest/download/nezha-agent_%s_%s.zip", repo, osType, arch)
resp, err := http.Get(zipUrl)
if err != nil || resp.StatusCode != http.StatusOK {
// Try Gitee if GitHub fails
zipUrl = fmt.Sprintf("https://gitee.com/naibahq/agent/releases/latest/download/nezha-agent_%s_%s.zip", osType, arch)
resp, err = http.Get(zipUrl)
if err != nil || resp.StatusCode != http.StatusOK {
c.JSON(http.StatusBadGateway, gin.H{"error": "Failed to fetch agent binary from upstream"})
return
}
}
defer resp.Body.Close()
// Create a temporary file to store the zip
tmpZip, err := os.CreateTemp("", "nezha-agent-*.zip")
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create temp file"})
return
}
defer os.Remove(tmpZip.Name())
defer tmpZip.Close()
// Limit the download to 200MB to prevent DoS
limitReader := io.LimitReader(resp.Body, 200*1024*1024)
if _, err := io.Copy(tmpZip, limitReader); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save zip"})
return
}
// Re-open for reading
zipReader, err := zip.OpenReader(tmpZip.Name())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to open zip"})
return
}
defer zipReader.Close()
// Set headers for .tar.gz
c.Header("Content-Type", "application/gzip")
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=nezha-agent_%s_%s.tar.gz", osType, arch))
gw := gzip.NewWriter(c.Writer)
defer gw.Close()
tw := tar.NewWriter(gw)
defer tw.Close()
for _, f := range zipReader.File {
if f.FileInfo().IsDir() {
continue
}
// Security check: Limit uncompressed size to 100MB per file
if f.UncompressedSize64 > 100*1024*1024 {
continue
}
header, err := tar.FileInfoHeader(f.FileInfo(), "")
if err != nil {
continue
}
header.Name = f.Name
if err := tw.WriteHeader(header); err != nil {
continue
}
rc, err := f.Open()
if err != nil {
continue
}
// Use LimitReader as a secondary defense for gosec (G110)
if _, err := io.Copy(tw, io.LimitReader(rc, 100*1024*1024)); err != nil {
rc.Close()
continue
}
rc.Close()
}
}
@@ -0,0 +1,95 @@
$NZ_BASE_PATH = "C:\nezha"
$NZ_AGENT_PATH = "$NZ_BASE_PATH\agent"
function err($msg) {
Write-Host $msg -ForegroundColor Red
}
function success($msg) {
Write-Host $msg -ForegroundColor Green
}
function info($msg) {
Write-Host $msg -ForegroundColor Yellow
}
function env_check() {
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
"AMD64" { $global:os_arch = "amd64" }
"x86" { $global:os_arch = "386" }
"ARM64" { $global:os_arch = "arm64" }
default { err "Unknown architecture: $arch"; exit 1 }
}
$global:os = "windows"
}
function install() {
info "Installing nezha-agent..."
if ($env:NZ_DASHBOARD_URL) {
$NZ_AGENT_URL = "$($env:NZ_DASHBOARD_URL)/script/bin/$global:os/$global:os_arch"
} else {
$NZ_AGENT_URL = "https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_$global:os`_$global:os_arch.zip"
}
$dest = "$env:TEMP\nezha-agent.zip"
try {
Invoke-WebRequest -Uri $NZ_AGENT_URL -OutFile $dest
} catch {
err "Download nezha-agent failed, check your network connectivity"
exit 1
}
if (!(Test-Path $NZ_AGENT_PATH)) {
New-Item -ItemType Directory -Path $NZ_AGENT_PATH
}
Expand-Archive -Path $dest -DestinationPath $NZ_AGENT_PATH -Force
Remove-Item $dest
$path = "$NZ_AGENT_PATH\config.yml"
if (Test-Path $path) {
$random = -join ((97..122) + (48..57) | Get-Random -Count 5 | ForEach-Object { [char]$_ })
$path = "$NZ_AGENT_PATH\config-$random.yml"
}
if (!($env:NZ_SERVER)) {
err "NZ_SERVER should not be empty"
exit 1
}
if (!($env:NZ_CLIENT_SECRET)) {
err "NZ_CLIENT_SECRET should not be empty"
exit 1
}
$args = "service -c $path uninstall"
Start-Process -FilePath "$NZ_AGENT_PATH\nezha-agent.exe" -ArgumentList $args -Wait -WindowStyle Hidden -ErrorAction SilentlyContinue
$env_str = "NZ_UUID=$($env:NZ_UUID) NZ_SERVER=$($env:NZ_SERVER) NZ_CLIENT_SECRET=$($env:NZ_CLIENT_SECRET) NZ_TLS=$($env:NZ_TLS) NZ_DISABLE_AUTO_UPDATE=$($env:NZ_DISABLE_AUTO_UPDATE) NZ_DISABLE_FORCE_UPDATE=$($env:NZ_DISABLE_FORCE_UPDATE) NZ_DISABLE_COMMAND_EXECUTE=$($env:NZ_DISABLE_COMMAND_EXECUTE) NZ_SKIP_CONNECTION_COUNT=$($env:NZ_SKIP_CONNECTION_COUNT)"
# PowerShell env setting is different, but nezha-agent handles these env vars
$args = "service -c $path install"
# Set env vars for the process
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = "$NZ_AGENT_PATH\nezha-agent.exe"
$psi.Arguments = $args
$psi.EnvironmentVariables["NZ_SERVER"] = $env:NZ_SERVER
$psi.EnvironmentVariables["NZ_TLS"] = $env:NZ_TLS
$psi.EnvironmentVariables["NZ_CLIENT_SECRET"] = $env:NZ_CLIENT_SECRET
if ($env:NZ_UUID) { $psi.EnvironmentVariables["NZ_UUID"] = $env:NZ_UUID }
$proc = [System.Diagnostics.Process]::Start($psi)
$proc.WaitForExit()
if ($proc.ExitCode -ne 0) {
err "Install nezha-agent service failed"
exit 1
}
success "nezha-agent successfully installed"
}
env_check
install
+162
View File
@@ -0,0 +1,162 @@
#!/bin/sh
NZ_BASE_PATH="/opt/nezha"
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'
err() {
printf "${red}%s${plain}\n" "$*" >&2
}
success() {
printf "${green}%s${plain}\n" "$*"
}
info() {
printf "${yellow}%s${plain}\n" "$*"
}
sudo() {
myEUID=$(id -ru)
if [ "$myEUID" -ne 0 ]; then
if command -v sudo > /dev/null 2>&1; then
command sudo "$@"
else
err "ERROR: sudo is not installed on the system, the action cannot be proceeded."
exit 1
fi
else
"$@"
fi
}
deps_check() {
local deps="curl tar grep"
local _err=0
local missing=""
for dep in $deps; do
if ! command -v "$dep" >/dev/null 2>&1; then
_err=1
missing="${missing} $dep"
fi
done
if [ "$_err" -ne 0 ]; then
err "Missing dependencies:$missing. Please install them and try again."
exit 1
fi
}
env_check() {
mach=$(uname -m)
case "$mach" in
amd64|x86_64) os_arch="amd64" ;;
i386|i686) os_arch="386" ;;
aarch64|arm64) os_arch="arm64" ;;
*arm*) os_arch="arm" ;;
s390x) os_arch="s390x" ;;
riscv64) os_arch="riscv64" ;;
mips) os_arch="mips" ;;
mipsel|mipsle) os_arch="mipsle" ;;
loongarch64) os_arch="loong64" ;;
*) err "Unknown architecture: $mach"; exit 1 ;;
esac
system=$(uname)
case "$system" in
*Linux*) os="linux" ;;
*Darwin*) os="darwin" ;;
*FreeBSD*) os="freebsd" ;;
*) err "Unknown architecture: $system"; exit 1 ;;
esac
}
init() {
deps_check
env_check
}
install() {
info "Installing nezha-agent..."
if [ -n "$NZ_DASHBOARD_URL" ]; then
NZ_AGENT_URL="${NZ_DASHBOARD_URL}/script/bin/${os}/${os_arch}"
FILE_EXT="tar.gz"
else
# Fallback to GitHub
NZ_AGENT_URL="https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_${os}_${os_arch}.zip"
FILE_EXT="zip"
info "NZ_DASHBOARD_URL not found, falling back to GitHub..."
fi
_cmd="curl -fsSL \"$NZ_AGENT_URL\" -o /tmp/nezha-agent.${FILE_EXT}"
if ! eval "$_cmd"; then
err "Download nezha-agent failed from $NZ_AGENT_URL, check your network connectivity"
exit 1
fi
sudo mkdir -p $NZ_AGENT_PATH
if [ "$FILE_EXT" = "tar.gz" ]; then
sudo tar -zxf /tmp/nezha-agent.tar.gz -C $NZ_AGENT_PATH
else
if command -v unzip >/dev/null 2>&1; then
sudo unzip -qo /tmp/nezha-agent.zip -d $NZ_AGENT_PATH
else
err "unzip not found, and could not use tar for zip file. Please install unzip or use a dashboard that supports tar.gz conversion."
exit 1
fi
fi
sudo rm -rf /tmp/nezha-agent.${FILE_EXT}
path="$NZ_AGENT_PATH/config.yml"
if [ -f "$path" ]; then
random=$(LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 5)
path=$(printf "%s" "$NZ_AGENT_PATH/config-$random.yml")
fi
if [ -z "$NZ_SERVER" ]; then
err "NZ_SERVER should not be empty"
exit 1
fi
if [ -z "$NZ_CLIENT_SECRET" ]; then
err "NZ_CLIENT_SECRET should not be empty"
exit 1
fi
env="NZ_UUID=$NZ_UUID NZ_SERVER=$NZ_SERVER NZ_CLIENT_SECRET=$NZ_CLIENT_SECRET NZ_TLS=$NZ_TLS NZ_DISABLE_AUTO_UPDATE=$NZ_DISABLE_AUTO_UPDATE NZ_DISABLE_FORCE_UPDATE=$DISABLE_FORCE_UPDATE NZ_DISABLE_COMMAND_EXECUTE=$NZ_DISABLE_COMMAND_EXECUTE NZ_SKIP_CONNECTION_COUNT=$NZ_SKIP_CONNECTION_COUNT"
sudo "${NZ_AGENT_PATH}"/nezha-agent service -c "$path" uninstall >/dev/null 2>&1
_cmd="sudo env $env $NZ_AGENT_PATH/nezha-agent service -c $path install"
if ! eval "$_cmd"; then
err "Install nezha-agent service failed"
sudo "${NZ_AGENT_PATH}"/nezha-agent service -c "$path" uninstall >/dev/null 2>&1
exit 1
fi
success "nezha-agent successfully installed"
}
uninstall() {
find "$NZ_AGENT_PATH" -type f -name "*config*.yml" | while read -r file; do
sudo "$NZ_AGENT_PATH/nezha-agent" service -c "$file" uninstall
sudo rm "$file"
done
info "Uninstallation completed."
}
if [ "$1" = "uninstall" ]; then
uninstall
exit
fi
init
install
+2 -2
View File
@@ -21,6 +21,8 @@ require (
github.com/libdns/cloudflare v0.2.2 github.com/libdns/cloudflare v0.2.2
github.com/libdns/he v1.2.1 github.com/libdns/he v1.2.1
github.com/libdns/libdns v1.1.1 github.com/libdns/libdns v1.1.1
github.com/likexian/whois v1.15.7
github.com/likexian/whois-parser v1.24.21
github.com/miekg/dns v1.1.72 github.com/miekg/dns v1.1.72
github.com/nezhahq/libdns-tencentcloud v0.0.0-20250501081622-bd293105845a github.com/nezhahq/libdns-tencentcloud v0.0.0-20250501081622-bd293105845a
github.com/ory/graceful v0.2.0 github.com/ory/graceful v0.2.0
@@ -86,8 +88,6 @@ require (
github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect
github.com/likexian/gokit v0.25.16 // indirect github.com/likexian/gokit v0.25.16 // indirect
github.com/likexian/whois v1.15.7 // indirect
github.com/likexian/whois-parser v1.24.21 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.37 // indirect github.com/mattn/go-sqlite3 v1.14.37 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
+95
View File
@@ -0,0 +1,95 @@
$NZ_BASE_PATH = "C:\nezha"
$NZ_AGENT_PATH = "$NZ_BASE_PATH\agent"
function err($msg) {
Write-Host $msg -ForegroundColor Red
}
function success($msg) {
Write-Host $msg -ForegroundColor Green
}
function info($msg) {
Write-Host $msg -ForegroundColor Yellow
}
function env_check() {
$arch = $env:PROCESSOR_ARCHITECTURE
switch ($arch) {
"AMD64" { $global:os_arch = "amd64" }
"x86" { $global:os_arch = "386" }
"ARM64" { $global:os_arch = "arm64" }
default { err "Unknown architecture: $arch"; exit 1 }
}
$global:os = "windows"
}
function install() {
info "Installing nezha-agent..."
if ($env:NZ_DASHBOARD_URL) {
$NZ_AGENT_URL = "$($env:NZ_DASHBOARD_URL)/script/bin/$global:os/$global:os_arch"
} else {
$NZ_AGENT_URL = "https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_$global:os`_$global:os_arch.zip"
}
$dest = "$env:TEMP\nezha-agent.zip"
try {
Invoke-WebRequest -Uri $NZ_AGENT_URL -OutFile $dest
} catch {
err "Download nezha-agent failed, check your network connectivity"
exit 1
}
if (!(Test-Path $NZ_AGENT_PATH)) {
New-Item -ItemType Directory -Path $NZ_AGENT_PATH
}
Expand-Archive -Path $dest -DestinationPath $NZ_AGENT_PATH -Force
Remove-Item $dest
$path = "$NZ_AGENT_PATH\config.yml"
if (Test-Path $path) {
$random = -join ((97..122) + (48..57) | Get-Random -Count 5 | ForEach-Object { [char]$_ })
$path = "$NZ_AGENT_PATH\config-$random.yml"
}
if (!($env:NZ_SERVER)) {
err "NZ_SERVER should not be empty"
exit 1
}
if (!($env:NZ_CLIENT_SECRET)) {
err "NZ_CLIENT_SECRET should not be empty"
exit 1
}
$args = "service -c $path uninstall"
Start-Process -FilePath "$NZ_AGENT_PATH\nezha-agent.exe" -ArgumentList $args -Wait -WindowStyle Hidden -ErrorAction SilentlyContinue
$env_str = "NZ_UUID=$($env:NZ_UUID) NZ_SERVER=$($env:NZ_SERVER) NZ_CLIENT_SECRET=$($env:NZ_CLIENT_SECRET) NZ_TLS=$($env:NZ_TLS) NZ_DISABLE_AUTO_UPDATE=$($env:NZ_DISABLE_AUTO_UPDATE) NZ_DISABLE_FORCE_UPDATE=$($env:NZ_DISABLE_FORCE_UPDATE) NZ_DISABLE_COMMAND_EXECUTE=$($env:NZ_DISABLE_COMMAND_EXECUTE) NZ_SKIP_CONNECTION_COUNT=$($env:NZ_SKIP_CONNECTION_COUNT)"
# PowerShell env setting is different, but nezha-agent handles these env vars
$args = "service -c $path install"
# Set env vars for the process
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = "$NZ_AGENT_PATH\nezha-agent.exe"
$psi.Arguments = $args
$psi.EnvironmentVariables["NZ_SERVER"] = $env:NZ_SERVER
$psi.EnvironmentVariables["NZ_TLS"] = $env:NZ_TLS
$psi.EnvironmentVariables["NZ_CLIENT_SECRET"] = $env:NZ_CLIENT_SECRET
if ($env:NZ_UUID) { $psi.EnvironmentVariables["NZ_UUID"] = $env:NZ_UUID }
$proc = [System.Diagnostics.Process]::Start($psi)
$proc.WaitForExit()
if ($proc.ExitCode -ne 0) {
err "Install nezha-agent service failed"
exit 1
}
success "nezha-agent successfully installed"
}
env_check
install
+162
View File
@@ -0,0 +1,162 @@
#!/bin/sh
NZ_BASE_PATH="/opt/nezha"
NZ_AGENT_PATH="${NZ_BASE_PATH}/agent"
red='\033[0;31m'
green='\033[0;32m'
yellow='\033[0;33m'
plain='\033[0m'
err() {
printf "${red}%s${plain}\n" "$*" >&2
}
success() {
printf "${green}%s${plain}\n" "$*"
}
info() {
printf "${yellow}%s${plain}\n" "$*"
}
sudo() {
myEUID=$(id -ru)
if [ "$myEUID" -ne 0 ]; then
if command -v sudo > /dev/null 2>&1; then
command sudo "$@"
else
err "ERROR: sudo is not installed on the system, the action cannot be proceeded."
exit 1
fi
else
"$@"
fi
}
deps_check() {
local deps="curl tar grep"
local _err=0
local missing=""
for dep in $deps; do
if ! command -v "$dep" >/dev/null 2>&1; then
_err=1
missing="${missing} $dep"
fi
done
if [ "$_err" -ne 0 ]; then
err "Missing dependencies:$missing. Please install them and try again."
exit 1
fi
}
env_check() {
mach=$(uname -m)
case "$mach" in
amd64|x86_64) os_arch="amd64" ;;
i386|i686) os_arch="386" ;;
aarch64|arm64) os_arch="arm64" ;;
*arm*) os_arch="arm" ;;
s390x) os_arch="s390x" ;;
riscv64) os_arch="riscv64" ;;
mips) os_arch="mips" ;;
mipsel|mipsle) os_arch="mipsle" ;;
loongarch64) os_arch="loong64" ;;
*) err "Unknown architecture: $mach"; exit 1 ;;
esac
system=$(uname)
case "$system" in
*Linux*) os="linux" ;;
*Darwin*) os="darwin" ;;
*FreeBSD*) os="freebsd" ;;
*) err "Unknown architecture: $system"; exit 1 ;;
esac
}
init() {
deps_check
env_check
}
install() {
info "Installing nezha-agent..."
if [ -n "$NZ_DASHBOARD_URL" ]; then
NZ_AGENT_URL="${NZ_DASHBOARD_URL}/script/bin/${os}/${os_arch}"
FILE_EXT="tar.gz"
else
# Fallback to GitHub
NZ_AGENT_URL="https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_${os}_${os_arch}.zip"
FILE_EXT="zip"
info "NZ_DASHBOARD_URL not found, falling back to GitHub..."
fi
_cmd="curl -fsSL \"$NZ_AGENT_URL\" -o /tmp/nezha-agent.${FILE_EXT}"
if ! eval "$_cmd"; then
err "Download nezha-agent failed from $NZ_AGENT_URL, check your network connectivity"
exit 1
fi
sudo mkdir -p $NZ_AGENT_PATH
if [ "$FILE_EXT" = "tar.gz" ]; then
sudo tar -zxf /tmp/nezha-agent.tar.gz -C $NZ_AGENT_PATH
else
if command -v unzip >/dev/null 2>&1; then
sudo unzip -qo /tmp/nezha-agent.zip -d $NZ_AGENT_PATH
else
err "unzip not found, and could not use tar for zip file. Please install unzip or use a dashboard that supports tar.gz conversion."
exit 1
fi
fi
sudo rm -rf /tmp/nezha-agent.${FILE_EXT}
path="$NZ_AGENT_PATH/config.yml"
if [ -f "$path" ]; then
random=$(LC_ALL=C tr -dc a-z0-9 </dev/urandom | head -c 5)
path=$(printf "%s" "$NZ_AGENT_PATH/config-$random.yml")
fi
if [ -z "$NZ_SERVER" ]; then
err "NZ_SERVER should not be empty"
exit 1
fi
if [ -z "$NZ_CLIENT_SECRET" ]; then
err "NZ_CLIENT_SECRET should not be empty"
exit 1
fi
env="NZ_UUID=$NZ_UUID NZ_SERVER=$NZ_SERVER NZ_CLIENT_SECRET=$NZ_CLIENT_SECRET NZ_TLS=$NZ_TLS NZ_DISABLE_AUTO_UPDATE=$NZ_DISABLE_AUTO_UPDATE NZ_DISABLE_FORCE_UPDATE=$DISABLE_FORCE_UPDATE NZ_DISABLE_COMMAND_EXECUTE=$NZ_DISABLE_COMMAND_EXECUTE NZ_SKIP_CONNECTION_COUNT=$NZ_SKIP_CONNECTION_COUNT"
sudo "${NZ_AGENT_PATH}"/nezha-agent service -c "$path" uninstall >/dev/null 2>&1
_cmd="sudo env $env $NZ_AGENT_PATH/nezha-agent service -c $path install"
if ! eval "$_cmd"; then
err "Install nezha-agent service failed"
sudo "${NZ_AGENT_PATH}"/nezha-agent service -c "$path" uninstall >/dev/null 2>&1
exit 1
fi
success "nezha-agent successfully installed"
}
uninstall() {
find "$NZ_AGENT_PATH" -type f -name "*config*.yml" | while read -r file; do
sudo "$NZ_AGENT_PATH/nezha-agent" service -c "$file" uninstall
sudo rm "$file"
done
info "Uninstallation completed."
}
if [ "$1" = "uninstall" ]; then
uninstall
exit
fi
init
install