mirror of
https://github.com/fankes/komari-agent.git
synced 2025-10-19 02:59:23 +08:00
feat: 增强安装脚本,添加 nssm 下载和配置功能
This commit is contained in:
205
install.ps1
205
install.ps1
@@ -1,26 +1,26 @@
|
|||||||
# Windows PowerShell installation script for Komari Agent
|
# Windows PowerShell installation script for Komari Agent
|
||||||
|
|
||||||
# Logging functions with colors
|
# Logging functions with colors
|
||||||
function Log-Info { Write-Host "[INFO] $($_)" -ForegroundColor Cyan }
|
function Log-Info { param([string]$Message) Write-Host "$Message" -ForegroundColor Cyan }
|
||||||
function Log-Success{ Write-Host "[SUCCESS] $($_)" -ForegroundColor Green }
|
function Log-Success { param([string]$Message) Write-Host "$Message" -ForegroundColor Green }
|
||||||
function Log-Warning{ Write-Host "[WARNING] $($_)" -ForegroundColor Yellow }
|
function Log-Warning { param([string]$Message) Write-Host "[WARNING] $Message" -ForegroundColor Yellow }
|
||||||
function Log-Error { Write-Host "[ERROR] $($_)" -ForegroundColor Red }
|
function Log-Error { param([string]$Message) Write-Host "[ERROR] $Message" -ForegroundColor Red }
|
||||||
function Log-Step { Write-Host "[STEP] $($_)" -ForegroundColor Magenta }
|
function Log-Step { param([string]$Message) Write-Host "$Message" -ForegroundColor Magenta }
|
||||||
function Log-Config { Write-Host "[CONFIG] $($_)" -ForegroundColor White }
|
function Log-Config { param([string]$Message) Write-Host "- $Message" -ForegroundColor White }
|
||||||
|
|
||||||
# Default parameters
|
# Default parameters
|
||||||
$InstallDir = Join-Path $Env:ProgramFiles "Komari"
|
$InstallDir = Join-Path $Env:ProgramFiles "Komari"
|
||||||
$ServiceName = "komari-agent"
|
$ServiceName = "komari-agent"
|
||||||
$GitHubProxy = ""
|
$GitHubProxy = ""
|
||||||
$KomariArgs = @()
|
$KomariArgs = @()
|
||||||
|
|
||||||
# Parse script arguments
|
# Parse script arguments
|
||||||
for ($i = 0; $i -lt $args.Count; $i++) {
|
for ($i = 0; $i -lt $args.Count; $i++) {
|
||||||
switch ($args[$i]) {
|
switch ($args[$i]) {
|
||||||
"--install-dir" { $InstallDir = $args[$i+1]; $i++; continue }
|
"--install-dir" { $InstallDir = $args[$i + 1]; $i++; continue }
|
||||||
"--install-service-name" { $ServiceName = $args[$i+1]; $i++; continue }
|
"--install-service-name" { $ServiceName = $args[$i + 1]; $i++; continue }
|
||||||
"--install-ghproxy" { $GitHubProxy = $args[$i+1]; $i++; continue }
|
"--install-ghproxy" { $GitHubProxy = $args[$i + 1]; $i++; continue }
|
||||||
Default { $KomariArgs += $args[$i] }
|
Default { $KomariArgs += $args[$i] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +41,118 @@ switch ($env:PROCESSOR_ARCHITECTURE) {
|
|||||||
Default { Log-Error "Unsupported architecture: $env:PROCESSOR_ARCHITECTURE"; exit 1 }
|
Default { Log-Error "Unsupported architecture: $env:PROCESSOR_ARCHITECTURE"; exit 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Ensure installation directory exists for nssm and agent
|
||||||
|
Log-Step "Ensuring installation directory exists: $InstallDir"
|
||||||
|
New-Item -ItemType Directory -Path $InstallDir -Force -ErrorAction SilentlyContinue | Out-Null # Ensure $InstallDir exists
|
||||||
|
|
||||||
|
# Check for nssm and download if not present
|
||||||
|
$nssmExeToUse = Join-Path $InstallDir "nssm.exe"
|
||||||
|
|
||||||
|
# First, check if nssm is in PATH and is functional
|
||||||
|
$nssmCmd = Get-Command nssm -ErrorAction SilentlyContinue
|
||||||
|
if ($nssmCmd) {
|
||||||
|
Log-Info "nssm found in PATH at $($nssmCmd.Source)."
|
||||||
|
try {
|
||||||
|
$nssmVersionOutput = nssm version 2>&1
|
||||||
|
Log-Info "Detected nssm version: $nssmVersionOutput"
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Log-Warning "nssm found in PATH failed to execute 'nssm version'. Will attempt to use/download local copy. Error: $_"
|
||||||
|
$nssmCmd = $null # Force re-evaluation for local copy or download
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If nssm not found in PATH or the one in PATH failed, check local $InstallDir
|
||||||
|
if (-not $nssmCmd) {
|
||||||
|
if (Test-Path $nssmExeToUse) {
|
||||||
|
Log-Info "nssm found at $nssmExeToUse. Attempting to use it by adding $InstallDir to PATH."
|
||||||
|
$env:Path = "$($InstallDir);$($env:Path)"
|
||||||
|
$nssmCmd = Get-Command nssm -ErrorAction SilentlyContinue
|
||||||
|
if ($nssmCmd) {
|
||||||
|
try {
|
||||||
|
$nssmVersionOutput = nssm version 2>&1
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Log-Warning "nssm from $InstallDir failed to execute 'nssm version'. Error: $_"
|
||||||
|
$nssmCmd = $null # Mark as unusable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log-Warning "Failed to make nssm from $nssmExeToUse available via PATH. Will attempt download."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# If still no usable nssm command, proceed to download
|
||||||
|
if (-not $nssmCmd) {
|
||||||
|
Log-Info "nssm not found or not usable. Attempting to download to $InstallDir..."
|
||||||
|
$NssmVersion = "2.24"
|
||||||
|
$NssmZipUrl = "https://nssm.cc/release/nssm-$NssmVersion.zip"
|
||||||
|
$TempNssmZipPath = Join-Path $env:TEMP "nssm-$NssmVersion.zip"
|
||||||
|
$TempExtractDir = Join-Path $env:TEMP "nssm_extract_temp"
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log-Info "Downloading nssm from $NssmZipUrl..."
|
||||||
|
Invoke-WebRequest -Uri $NssmZipUrl -OutFile $TempNssmZipPath -UseBasicParsing
|
||||||
|
|
||||||
|
if (Test-Path $TempExtractDir) { Remove-Item -Recurse -Force $TempExtractDir }
|
||||||
|
New-Item -ItemType Directory -Path $TempExtractDir -Force | Out-Null
|
||||||
|
Expand-Archive -Path $TempNssmZipPath -DestinationPath $TempExtractDir -Force
|
||||||
|
|
||||||
|
$NssmSourceDirInsideZip = "nssm-$NssmVersion" # Used for Get-ChildItem search path
|
||||||
|
# The path part within the extracted nssm folder, e.g., "nssm-2.24\win32"
|
||||||
|
# 'win32' nssm is used for both 'amd64' and 'arm64' PowerShell architectures.
|
||||||
|
$NssmArchSubDir = Join-Path "nssm-$NssmVersion" "win32"
|
||||||
|
$NssmSourceExePath = Join-Path (Join-Path $TempExtractDir $NssmArchSubDir) "nssm.exe"
|
||||||
|
|
||||||
|
if (-not (Test-Path $NssmSourceExePath)) {
|
||||||
|
Log-Error "Could not find nssm.exe at expected path: $NssmSourceExePath after extraction."
|
||||||
|
# Fallback search for nssm.exe within the extracted directory
|
||||||
|
$foundNssmFallback = Get-ChildItem -Path $TempExtractDir -Recurse -Filter "nssm.exe" |
|
||||||
|
Where-Object { $_.FullName -like "*$NssmArchSubDir\nssm.exe" } |
|
||||||
|
Select-Object -First 1
|
||||||
|
if ($foundNssmFallback) {
|
||||||
|
Log-Warning "Found nssm.exe at $($foundNssmFallback.FullName) using fallback search. Using this."
|
||||||
|
$NssmSourceExePath = $foundNssmFallback.FullName
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log-Error "nssm.exe ($NssmArchSubDir) still not found in $TempExtractDir. Please install nssm manually (from https://nssm.cc) and ensure it's in your PATH."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Copy-Item -Path $NssmSourceExePath -Destination $nssmExeToUse -Force
|
||||||
|
|
||||||
|
$env:Path = "$($InstallDir);$($env:Path)"
|
||||||
|
$nssmCmd = Get-Command nssm -ErrorAction SilentlyContinue # Re-check after adding to PATH
|
||||||
|
if ($nssmCmd) {
|
||||||
|
Log-Success "Downloaded nssm is now configured and available in PATH."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log-Error "Failed to configure downloaded nssm in PATH from $nssmExeToUse. Please ensure $InstallDir is in your system PATH or nssm is installed globally."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Log-Error "Failed to download or configure nssm: $_"
|
||||||
|
Log-Error "Please install nssm manually from https://nssm.cc and ensure nssm.exe is in your PATH."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (Test-Path $TempNssmZipPath) { Remove-Item $TempNssmZipPath -Force -ErrorAction SilentlyContinue }
|
||||||
|
if (Test-Path $TempExtractDir) { Remove-Item $TempExtractDir -Recurse -Force -ErrorAction SilentlyContinue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Final check that nssm is operational
|
||||||
|
try {
|
||||||
|
$nssmVersionOutput = nssm version 2>&1
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Log-Error "nssm command failed to execute even after setup attempts. Please check the nssm installation and PATH. Error: $_"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
Log-Step "Installation configuration:"
|
Log-Step "Installation configuration:"
|
||||||
Log-Config "Service name: $ServiceName"
|
Log-Config "Service name: $ServiceName"
|
||||||
Log-Config "Install directory: $InstallDir"
|
Log-Config "Install directory: $InstallDir"
|
||||||
@@ -48,21 +160,39 @@ Log-Config "GitHub proxy: $ProxyDisplay"
|
|||||||
Log-Config "Agent arguments: $($KomariArgs -join ' ')"
|
Log-Config "Agent arguments: $($KomariArgs -join ' ')"
|
||||||
|
|
||||||
# Paths
|
# Paths
|
||||||
$BinaryName = "komari-agent-windows-$arch.exe"
|
$BinaryName = "komari-agent-windows-$arch.exe"
|
||||||
$AgentPath = Join-Path $InstallDir $BinaryName
|
$AgentPath = Join-Path $InstallDir "komari-agent.exe"
|
||||||
|
|
||||||
# Uninstall previous service and binary
|
# Uninstall previous service and binary
|
||||||
function Uninstall-Previous {
|
function Uninstall-Previous {
|
||||||
Log-Step "Checking for existing service..."
|
Log-Step "Checking for existing service..."
|
||||||
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
# Check if service exists using nssm status, as Get-Service might not work for nssm services if not properly registered
|
||||||
if ($svc) {
|
$serviceStatus = nssm status $ServiceName 2>&1
|
||||||
|
if ($serviceStatus -notmatch "SERVICE_STOPPED" -and $serviceStatus -notmatch "does not exist") {
|
||||||
Log-Info "Stopping service $ServiceName..."
|
Log-Info "Stopping service $ServiceName..."
|
||||||
Stop-Service $ServiceName -Force
|
nssm stop $ServiceName 2>&1 | Out-Null
|
||||||
Log-Info "Deleting service $ServiceName..."
|
|
||||||
sc.exe delete $ServiceName | Out-Null
|
|
||||||
}
|
}
|
||||||
|
# Attempt to remove the service using nssm
|
||||||
|
# We check if it exists first by trying to get its status.
|
||||||
|
# nssm remove will succeed if the service exists, and fail otherwise.
|
||||||
|
# We add confirm to avoid interactive prompts.
|
||||||
|
$removeOutput = nssm remove $ServiceName confirm 2>&1
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
}
|
||||||
|
elseif ($removeOutput -match "Can't open service! (The specified service does not exist as an installed service.)" -or $removeOutput -match "No such service" -or $removeOutput -match "does not exist") {
|
||||||
|
Log-Info "Service $ServiceName does not exist or was already removed."
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# If nssm remove fails for other reasons, try sc.exe delete as a fallback for older installations
|
||||||
|
$svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
|
||||||
|
if ($svc) {
|
||||||
|
Stop-Service $ServiceName -Force -ErrorAction SilentlyContinue
|
||||||
|
sc.exe delete $ServiceName | Out-Null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Test-Path $AgentPath) {
|
if (Test-Path $AgentPath) {
|
||||||
Log-Info "Removing old binary..."
|
Log-Warning "Removing old binary..."
|
||||||
Remove-Item $AgentPath -Force
|
Remove-Item $AgentPath -Force
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,39 +200,46 @@ Uninstall-Previous
|
|||||||
|
|
||||||
# Fetch latest release version
|
# Fetch latest release version
|
||||||
$ApiUrl = "https://api.github.com/repos/komari-monitor/komari-agent/releases/latest"
|
$ApiUrl = "https://api.github.com/repos/komari-monitor/komari-agent/releases/latest"
|
||||||
Log-Step "Fetching latest version from GitHub API..."
|
|
||||||
try {
|
try {
|
||||||
$release = Invoke-RestMethod -Uri $ApiUrl -UseBasicParsing
|
$release = Invoke-RestMethod -Uri $ApiUrl -UseBasicParsing
|
||||||
$latestVersion = $release.tag_name
|
$latestVersion = $release.tag_name
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
Log-Error "Failed to fetch latest version: $_"
|
Log-Error "Failed to fetch latest version: $_"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
Log-Success "Latest version: $latestVersion"
|
Log-Success "Latest version: $latestVersion"
|
||||||
|
|
||||||
# Construct download URL
|
# Construct download URL
|
||||||
$BinaryName = "komari-agent-windows-$arch.exe"
|
$BinaryName = "komari-agent-windows-$arch.exe"
|
||||||
$DownloadUrl = if ($GitHubProxy) { "$GitHubProxy/https://github.com/komari-monitor/komari-agent/releases/download/$latestVersion/$BinaryName" } else { "https://github.com/komari-monitor/komari-agent/releases/download/$latestVersion/$BinaryName" }
|
$DownloadUrl = if ($GitHubProxy) { "$GitHubProxy/https://github.com/komari-monitor/komari-agent/releases/download/$latestVersion/$BinaryName" } else { "https://github.com/komari-monitor/komari-agent/releases/download/$latestVersion/$BinaryName" }
|
||||||
|
|
||||||
# Download and install
|
# Download and install
|
||||||
Log-Step "Preparing installation directory..."
|
|
||||||
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
|
||||||
Log-Step "Downloading $BinaryName..."
|
|
||||||
Log-Info "URL: $DownloadUrl"
|
Log-Info "URL: $DownloadUrl"
|
||||||
try {
|
try {
|
||||||
Invoke-WebRequest -Uri $DownloadUrl -OutFile $AgentPath -UseBasicParsing
|
Invoke-WebRequest -Uri $DownloadUrl -OutFile $AgentPath -UseBasicParsing
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
Log-Error "Download failed: $_"
|
Log-Error "Download failed: $_"
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
Log-Success "Downloaded and saved to $AgentPath"
|
Log-Success "Downloaded and saved to $AgentPath"
|
||||||
|
|
||||||
# Register and start service
|
# Register and start service
|
||||||
Log-Step "Configuring Windows service..."
|
Log-Step "Configuring Windows service with nssm..."
|
||||||
$argString = $KomariArgs -join ' '
|
$argString = $KomariArgs -join ' '
|
||||||
New-Service -Name $ServiceName -BinaryPathName "`"$AgentPath`" $argString" -DisplayName "Komari Agent Service" -StartupType Automatic
|
# Ensure InstallDir and AgentPath are quoted if they contain spaces
|
||||||
Start-Service $ServiceName
|
$quotedAgentPath = "`"$AgentPath`""
|
||||||
Log-Success "Service $ServiceName installed and started."
|
nssm install $ServiceName $quotedAgentPath $argString
|
||||||
|
# Set display name and startup type using nssm
|
||||||
|
nssm set $ServiceName DisplayName "Komari Agent Service"
|
||||||
|
nssm set $ServiceName Start SERVICE_AUTO_START
|
||||||
|
nssm set $ServiceName AppExit Default Restart
|
||||||
|
nssm set $ServiceName AppRestartDelay 5000
|
||||||
|
# Start the service using nssm
|
||||||
|
nssm start $ServiceName
|
||||||
|
Log-Success "Service $ServiceName installed and started using nssm."
|
||||||
|
|
||||||
Log-Success "Komari Agent installation completed!"
|
Log-Success "Komari Agent installation completed!"
|
||||||
Log-Config "Service name: $ServiceName"
|
Log-Config "Service name: $ServiceName"
|
||||||
|
Reference in New Issue
Block a user