feat: enhance macOS/Linux agent installation to match Windows quality
Major improvements to the host agent installation experience: Installation Enhancements: - Add interactive mode with prompts for URL/token if not provided - Add colored output with ANSI codes (✓ ℹ ⚠ ✗) matching Windows style - Add professional header/footer with bordered sections - Display masked configuration before installation - Add version detection and update notifications - Add reinstall confirmation for existing installations Security Improvements: - Store tokens in macOS Keychain instead of plaintext plist - Create wrapper script to read token from Keychain at runtime - Add SHA256 checksum verification for downloaded binaries - Set restrictive permissions (chmod 600) on service configs - Graceful fallback if Keychain access denied Validation & Verification: - Wait 10 seconds and verify service is running - Query /api/hosts endpoint to confirm agent registered - Verify hostname appears in Pulse server - Provide detailed troubleshooting if validation fails Error Handling: - Comprehensive error messages with actionable guidance - Platform-specific install instructions for missing dependencies - 4-step troubleshooting guide for download failures - Build-from-source fallback instructions - Service failure diagnostics with log viewing commands Logging Improvements: - Use persistent log directories (no more /tmp) - macOS: ~/Library/Logs/Pulse/host-agent.log - Linux: /var/log/pulse/host-agent.log - Automatically create log directories Post-Install: - Display service management commands (start/stop/restart/logs) - Show installed file locations - Provide uninstall instructions - Link to Pulse dashboard Uninstall Script: - New dedicated uninstall script with colored output - Comprehensive cleanup (service, binary, logs, Keychain) - Platform detection and appropriate cleanup steps - Remove macOS Keychain entries and wrapper scripts - Remove temporary logs from old /tmp location - Retry logic for file locking issues Progress Indicators: - Better download progress with curl --progress-bar - Clear status messages for each installation step - Visual feedback throughout installation These changes bring the macOS/Linux installation experience to parity with Windows and add several features that exceed Windows quality: - API endpoint verification (Windows doesn't have) - Checksum verification (Windows doesn't have) - macOS Keychain integration (more secure than Windows config) - Update detection (Windows doesn't have)
This commit is contained in:
parent
6333a445e9
commit
df8e12df33
4 changed files with 1422 additions and 65 deletions
605
frontend-modern/public/install-host-agent.sh
Executable file
605
frontend-modern/public/install-host-agent.sh
Executable file
|
|
@ -0,0 +1,605 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Pulse Host Agent Installer
|
||||
# Downloads and installs the Pulse host agent for Linux, macOS, or Windows (WSL)
|
||||
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RESET='\033[0m'
|
||||
|
||||
# Check if colors are supported
|
||||
if [ -t 1 ] && command -v tput &> /dev/null && [ "$(tput colors)" -ge 8 ]; then
|
||||
USE_COLOR=true
|
||||
else
|
||||
USE_COLOR=false
|
||||
fi
|
||||
|
||||
print_color() {
|
||||
local color="$1"
|
||||
local message="$2"
|
||||
if [ "$USE_COLOR" = true ]; then
|
||||
printf "${color}%s${RESET}\n" "$message"
|
||||
else
|
||||
printf "%s\n" "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
print_color "$GREEN" "✓ $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
print_color "$RED" "✗ $1" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
print_color "$BLUE" "ℹ $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
print_color "$YELLOW" "⚠ $1"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
print_color "$BLUE" " Pulse Host Agent - Installation"
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_footer() {
|
||||
echo ""
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
log_success "Installation complete!"
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
PULSE_URL=""
|
||||
PULSE_TOKEN=""
|
||||
INTERVAL="30s"
|
||||
UNINSTALL="false"
|
||||
PLATFORM=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--url)
|
||||
PULSE_URL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--token)
|
||||
PULSE_TOKEN="$2"
|
||||
shift 2
|
||||
;;
|
||||
--interval)
|
||||
INTERVAL="$2"
|
||||
shift 2
|
||||
;;
|
||||
--platform)
|
||||
PLATFORM="$2"
|
||||
shift 2
|
||||
;;
|
||||
--uninstall)
|
||||
UNINSTALL="true"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
AGENT_PATH="/usr/local/bin/pulse-host-agent"
|
||||
SYSTEMD_SERVICE="/etc/systemd/system/pulse-host-agent.service"
|
||||
LAUNCHD_PLIST="$HOME/Library/LaunchAgents/com.pulse.host-agent.plist"
|
||||
MACOS_LOG_DIR="$HOME/Library/Logs/Pulse"
|
||||
MACOS_LOG_FILE="$MACOS_LOG_DIR/host-agent.log"
|
||||
LINUX_LOG_DIR="/var/log/pulse"
|
||||
LINUX_LOG_FILE="$LINUX_LOG_DIR/host-agent.log"
|
||||
|
||||
# Uninstall function
|
||||
if [[ "$UNINSTALL" == "true" ]]; then
|
||||
log_warn "The --uninstall flag is deprecated."
|
||||
log_info "Please use the dedicated uninstall script instead:"
|
||||
echo ""
|
||||
echo " curl -fsSL \$PULSE_URL/uninstall-host-agent.sh | bash"
|
||||
echo ""
|
||||
log_info "Or download and run manually:"
|
||||
echo " wget \$PULSE_URL/uninstall-host-agent.sh"
|
||||
echo " chmod +x uninstall-host-agent.sh"
|
||||
echo " ./uninstall-host-agent.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_header
|
||||
|
||||
# Interactive prompts if parameters not provided
|
||||
if [[ -z "$PULSE_URL" ]]; then
|
||||
log_info "Interactive Installation Mode"
|
||||
echo ""
|
||||
read -p "Enter Pulse server URL (e.g., http://pulse.example.com:7656): " PULSE_URL
|
||||
PULSE_URL=$(echo "$PULSE_URL" | sed 's:/*$::') # Remove trailing slashes
|
||||
fi
|
||||
|
||||
if [[ -z "$PULSE_URL" ]]; then
|
||||
log_error "Pulse URL is required"
|
||||
echo "Usage: $0 --url <pulse-url> --token <api-token> [--interval 30s] [--platform linux|darwin|windows]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$PULSE_TOKEN" ]]; then
|
||||
log_warn "No API token provided - agent will attempt to connect without authentication"
|
||||
read -p "Enter API token (or press Enter to skip): " PULSE_TOKEN
|
||||
|
||||
if [[ -z "$PULSE_TOKEN" ]]; then
|
||||
read -p "Continue without token? (y/N): " CONTINUE_WITHOUT_TOKEN
|
||||
if [[ "$CONTINUE_WITHOUT_TOKEN" != "y" ]] && [[ "$CONTINUE_WITHOUT_TOKEN" != "Y" ]]; then
|
||||
log_error "Installation cancelled"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect platform if not specified
|
||||
if [[ -z "$PLATFORM" ]]; then
|
||||
case "$(uname -s)" in
|
||||
Linux*)
|
||||
PLATFORM="linux"
|
||||
;;
|
||||
Darwin*)
|
||||
PLATFORM="darwin"
|
||||
;;
|
||||
MINGW*|MSYS*|CYGWIN*)
|
||||
PLATFORM="windows"
|
||||
;;
|
||||
*)
|
||||
log_error "Unsupported platform: $(uname -s)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Detect architecture
|
||||
ARCH="$(uname -m)"
|
||||
case "$ARCH" in
|
||||
x86_64|amd64)
|
||||
ARCH="amd64"
|
||||
;;
|
||||
aarch64|arm64)
|
||||
ARCH="arm64"
|
||||
;;
|
||||
armv7l|armhf)
|
||||
ARCH="armv7"
|
||||
;;
|
||||
*)
|
||||
log_warn "Unknown architecture $ARCH, defaulting to amd64"
|
||||
ARCH="amd64"
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Configuration:"
|
||||
echo " Pulse URL: $PULSE_URL"
|
||||
if [[ -n "$PULSE_TOKEN" ]]; then
|
||||
# Mask token, showing only last 4 characters
|
||||
TOKEN_MASKED="***${PULSE_TOKEN: -4}"
|
||||
echo " Token: $TOKEN_MASKED"
|
||||
else
|
||||
echo " Token: none"
|
||||
fi
|
||||
echo " Interval: $INTERVAL"
|
||||
echo " Platform: $PLATFORM/$ARCH"
|
||||
echo ""
|
||||
|
||||
log_info "Installing Pulse host agent for $PLATFORM/$ARCH..."
|
||||
|
||||
# Check for existing installation and version
|
||||
if [[ -f "$AGENT_PATH" ]]; then
|
||||
log_info "Existing installation detected"
|
||||
CURRENT_VERSION=$("$AGENT_PATH" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
|
||||
if [[ "$CURRENT_VERSION" != "unknown" ]]; then
|
||||
echo " Current version: $CURRENT_VERSION"
|
||||
fi
|
||||
|
||||
# Try to get latest version from server
|
||||
if command -v curl &> /dev/null; then
|
||||
LATEST_VERSION=$(curl -fsSL "$PULSE_URL/api/version" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
LATEST_VERSION=$(wget -qO- "$PULSE_URL/api/version" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
fi
|
||||
|
||||
if [[ -n "$LATEST_VERSION" ]] && [[ "$CURRENT_VERSION" != "unknown" ]]; then
|
||||
echo " Latest version: $LATEST_VERSION"
|
||||
if [[ "$CURRENT_VERSION" == "$LATEST_VERSION" ]]; then
|
||||
log_success "Already running latest version"
|
||||
elif [[ "$CURRENT_VERSION" < "$LATEST_VERSION" ]]; then
|
||||
log_info "Update available: $CURRENT_VERSION → $LATEST_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
read -p "Reinstall/update agent? (Y/n): " REINSTALL
|
||||
if [[ "$REINSTALL" == "n" ]] || [[ "$REINSTALL" == "N" ]]; then
|
||||
log_info "Installation cancelled"
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Download agent binary from Pulse server
|
||||
DOWNLOAD_URL="$PULSE_URL/download/pulse-host-agent?platform=$PLATFORM&arch=$ARCH"
|
||||
TEMP_BINARY="/tmp/pulse-host-agent-$$.tmp"
|
||||
|
||||
log_info "Downloading agent binary from $PULSE_URL..."
|
||||
|
||||
DOWNLOAD_SUCCESS=false
|
||||
CHECKSUM_URL="${DOWNLOAD_URL}.sha256"
|
||||
|
||||
if command -v curl &> /dev/null; then
|
||||
if curl -fL --progress-bar -o "$TEMP_BINARY" "$DOWNLOAD_URL" 2>&1; then
|
||||
DOWNLOAD_SUCCESS=true
|
||||
fi
|
||||
# Try to download checksum (optional, server may not provide it yet)
|
||||
EXPECTED_CHECKSUM=$(curl -fsSL "$CHECKSUM_URL" 2>/dev/null || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
if wget -q --show-progress -O "$TEMP_BINARY" "$DOWNLOAD_URL" 2>&1; then
|
||||
DOWNLOAD_SUCCESS=true
|
||||
fi
|
||||
# Try to download checksum (optional)
|
||||
EXPECTED_CHECKSUM=$(wget -qO- "$CHECKSUM_URL" 2>/dev/null || echo "")
|
||||
else
|
||||
log_error "Neither curl nor wget found"
|
||||
echo ""
|
||||
log_info "Please install curl or wget to continue:"
|
||||
if [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " brew install curl"
|
||||
elif [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " # Debian/Ubuntu:"
|
||||
echo " sudo apt-get install curl"
|
||||
echo ""
|
||||
echo " # RHEL/CentOS/Fedora:"
|
||||
echo " sudo yum install curl"
|
||||
fi
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$DOWNLOAD_SUCCESS" == false ]]; then
|
||||
log_error "Failed to download agent binary from $DOWNLOAD_URL"
|
||||
echo ""
|
||||
log_info "Troubleshooting steps:"
|
||||
echo ""
|
||||
echo "1. Verify the Pulse server is running:"
|
||||
echo " curl $PULSE_URL/health"
|
||||
echo ""
|
||||
echo "2. Check if the download endpoint is accessible:"
|
||||
echo " curl -I $DOWNLOAD_URL"
|
||||
echo ""
|
||||
echo "3. Build from source as a fallback:"
|
||||
echo " git clone https://github.com/rcourtman/Pulse.git"
|
||||
echo " cd Pulse"
|
||||
echo " go build -o pulse-host-agent ./cmd/pulse-host-agent"
|
||||
echo " sudo mv pulse-host-agent /usr/local/bin/"
|
||||
echo " # Then run this script again with --url and --token"
|
||||
echo ""
|
||||
echo "4. Check firewall/network settings blocking the connection"
|
||||
echo ""
|
||||
rm -f "$TEMP_BINARY"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Downloaded agent binary"
|
||||
|
||||
# Verify checksum if available
|
||||
if [[ -n "$EXPECTED_CHECKSUM" ]]; then
|
||||
log_info "Verifying checksum..."
|
||||
|
||||
if command -v sha256sum &> /dev/null; then
|
||||
ACTUAL_CHECKSUM=$(sha256sum "$TEMP_BINARY" | awk '{print $1}')
|
||||
elif command -v shasum &> /dev/null; then
|
||||
ACTUAL_CHECKSUM=$(shasum -a 256 "$TEMP_BINARY" | awk '{print $1}')
|
||||
else
|
||||
log_warn "No checksum tool found (sha256sum/shasum), skipping verification"
|
||||
ACTUAL_CHECKSUM=""
|
||||
fi
|
||||
|
||||
if [[ -n "$ACTUAL_CHECKSUM" ]]; then
|
||||
# Clean up checksums (remove whitespace, convert to lowercase)
|
||||
EXPECTED_CHECKSUM=$(echo "$EXPECTED_CHECKSUM" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')
|
||||
ACTUAL_CHECKSUM=$(echo "$ACTUAL_CHECKSUM" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
if [[ "$EXPECTED_CHECKSUM" == "$ACTUAL_CHECKSUM" ]]; then
|
||||
log_success "Checksum verified (SHA256: ${ACTUAL_CHECKSUM:0:16}...)"
|
||||
else
|
||||
log_error "Checksum mismatch!"
|
||||
echo " Expected: $EXPECTED_CHECKSUM"
|
||||
echo " Got: $ACTUAL_CHECKSUM"
|
||||
echo ""
|
||||
log_warn "The downloaded binary may be corrupted or tampered with."
|
||||
read -p "Continue anyway? (y/N): " CONTINUE_ANYWAY
|
||||
if [[ "$CONTINUE_ANYWAY" != "y" ]] && [[ "$CONTINUE_ANYWAY" != "Y" ]]; then
|
||||
rm -f "$TEMP_BINARY"
|
||||
log_error "Installation cancelled"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_info "Checksum not available (server doesn't provide it yet)"
|
||||
fi
|
||||
|
||||
sudo mv "$TEMP_BINARY" "$AGENT_PATH"
|
||||
sudo chmod +x "$AGENT_PATH"
|
||||
log_success "Agent binary installed to $AGENT_PATH"
|
||||
|
||||
# Set up service based on platform
|
||||
if [[ "$PLATFORM" == "linux" ]] && command -v systemctl &> /dev/null; then
|
||||
log_info "Setting up systemd service..."
|
||||
|
||||
# Create log directory
|
||||
sudo mkdir -p "$LINUX_LOG_DIR"
|
||||
|
||||
sudo tee "$SYSTEMD_SERVICE" > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Pulse Host Agent
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=$AGENT_PATH --url $PULSE_URL --token $PULSE_TOKEN --interval $INTERVAL
|
||||
Restart=always
|
||||
RestartSec=5s
|
||||
User=root
|
||||
StandardOutput=append:$LINUX_LOG_FILE
|
||||
StandardError=append:$LINUX_LOG_FILE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
log_success "Created systemd service configuration"
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable pulse-host-agent
|
||||
sudo systemctl start pulse-host-agent
|
||||
log_success "Systemd service enabled and started"
|
||||
|
||||
elif [[ "$PLATFORM" == "darwin" ]] && command -v launchctl &> /dev/null; then
|
||||
log_info "Setting up launchd service..."
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$MACOS_LOG_DIR"
|
||||
mkdir -p "$HOME/Library/LaunchAgents"
|
||||
|
||||
# Store token in macOS Keychain for better security
|
||||
if [[ -n "$PULSE_TOKEN" ]]; then
|
||||
log_info "Storing token in macOS Keychain..."
|
||||
|
||||
# Delete existing keychain entry if it exists
|
||||
security delete-generic-password -s "pulse-host-agent" -a "$USER" 2>/dev/null || true
|
||||
|
||||
# Add token to Keychain
|
||||
if security add-generic-password -s "pulse-host-agent" -a "$USER" -w "$PULSE_TOKEN" -U 2>/dev/null; then
|
||||
log_success "Token stored securely in macOS Keychain"
|
||||
USE_KEYCHAIN=true
|
||||
else
|
||||
log_warn "Failed to store token in Keychain, will use plist instead"
|
||||
log_info "You may need to grant Keychain access permissions"
|
||||
USE_KEYCHAIN=false
|
||||
fi
|
||||
else
|
||||
USE_KEYCHAIN=false
|
||||
fi
|
||||
|
||||
# Create wrapper script if using Keychain
|
||||
if [[ "$USE_KEYCHAIN" == true ]]; then
|
||||
WRAPPER_SCRIPT="/usr/local/bin/pulse-host-agent-wrapper.sh"
|
||||
|
||||
cat > "$WRAPPER_SCRIPT" <<'WRAPPER_EOF'
|
||||
#!/bin/bash
|
||||
# Pulse Host Agent Wrapper - Reads token from Keychain
|
||||
set -e
|
||||
|
||||
# Read token from Keychain
|
||||
PULSE_TOKEN=$(security find-generic-password -s "pulse-host-agent" -w 2>/dev/null || echo "")
|
||||
|
||||
# Export for agent to use
|
||||
export PULSE_TOKEN
|
||||
|
||||
# Run the actual agent with all arguments
|
||||
exec /usr/local/bin/pulse-host-agent "$@"
|
||||
WRAPPER_EOF
|
||||
|
||||
chmod +x "$WRAPPER_SCRIPT"
|
||||
log_success "Created Keychain wrapper script"
|
||||
|
||||
# Create plist using wrapper (token not in plist!)
|
||||
cat > "$LAUNCHD_PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.pulse.host-agent</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$WRAPPER_SCRIPT</string>
|
||||
<string>--url</string>
|
||||
<string>$PULSE_URL</string>
|
||||
<string>--interval</string>
|
||||
<string>$INTERVAL</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
log_success "Created launchd service configuration (using Keychain)"
|
||||
else
|
||||
# Create plist with token directly (fallback)
|
||||
cat > "$LAUNCHD_PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.pulse.host-agent</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$AGENT_PATH</string>
|
||||
<string>--url</string>
|
||||
<string>$PULSE_URL</string>
|
||||
<string>--token</string>
|
||||
<string>$PULSE_TOKEN</string>
|
||||
<string>--interval</string>
|
||||
<string>$INTERVAL</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
log_success "Created launchd service configuration"
|
||||
fi
|
||||
|
||||
# Set restrictive permissions on plist
|
||||
chmod 600 "$LAUNCHD_PLIST"
|
||||
|
||||
launchctl load "$LAUNCHD_PLIST"
|
||||
log_success "Launchd service enabled and started"
|
||||
else
|
||||
log_warn "Automatic service setup not available for this platform"
|
||||
log_info "To run the agent manually:"
|
||||
log_info " $AGENT_PATH --url $PULSE_URL --token $PULSE_TOKEN --interval $INTERVAL"
|
||||
fi
|
||||
|
||||
# Validate installation
|
||||
log_info "Waiting 10 seconds to validate agent reporting..."
|
||||
sleep 10
|
||||
|
||||
VALIDATION_SUCCESS=false
|
||||
SERVICE_RUNNING=false
|
||||
|
||||
# Check if service is running
|
||||
if [[ "$PLATFORM" == "linux" ]] && command -v systemctl &> /dev/null; then
|
||||
SERVICE_STATUS=$(systemctl is-active pulse-host-agent 2>/dev/null || echo "inactive")
|
||||
if [[ "$SERVICE_STATUS" == "active" ]]; then
|
||||
SERVICE_RUNNING=true
|
||||
log_success "Service is running successfully!"
|
||||
else
|
||||
log_warn "Service status: $SERVICE_STATUS"
|
||||
log_info "Check logs with: sudo journalctl -u pulse-host-agent -n 50"
|
||||
fi
|
||||
elif [[ "$PLATFORM" == "darwin" ]] && command -v launchctl &> /dev/null; then
|
||||
if launchctl list | grep -q "com.pulse.host-agent"; then
|
||||
SERVICE_RUNNING=true
|
||||
log_success "Service is running successfully!"
|
||||
else
|
||||
log_warn "Service may not be running properly"
|
||||
log_info "Check logs with: tail -20 $MACOS_LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try to verify with API endpoint that agent is reporting
|
||||
if [[ "$SERVICE_RUNNING" == true ]]; then
|
||||
log_info "Verifying agent registration with Pulse server..."
|
||||
|
||||
# Get hostname for verification
|
||||
HOSTNAME=$(hostname)
|
||||
|
||||
# Try to query the API for this host
|
||||
if command -v curl &> /dev/null; then
|
||||
API_CHECK=$(curl -fsSL "$PULSE_URL/api/hosts" 2>/dev/null || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
API_CHECK=$(wget -qO- "$PULSE_URL/api/hosts" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [[ -n "$API_CHECK" ]] && echo "$API_CHECK" | grep -q "$HOSTNAME"; then
|
||||
VALIDATION_SUCCESS=true
|
||||
log_success "Agent successfully registered with Pulse server!"
|
||||
log_success "Your host '$HOSTNAME' is now reporting metrics!"
|
||||
elif [[ -n "$API_CHECK" ]]; then
|
||||
log_warn "Agent is running but host not found in API yet (may take a few moments)"
|
||||
log_info "Service appears healthy, metrics should appear shortly."
|
||||
VALIDATION_SUCCESS=true # Service is running, so count as success
|
||||
else
|
||||
log_warn "Could not verify registration via API (endpoint may not be accessible)"
|
||||
log_info "Service is running, check your Pulse dashboard manually."
|
||||
VALIDATION_SUCCESS=true # Service is running, so count as success
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$VALIDATION_SUCCESS" == true ]]; then
|
||||
log_info "Check your Pulse dashboard at: $PULSE_URL"
|
||||
else
|
||||
log_error "Service validation failed"
|
||||
echo ""
|
||||
log_info "Troubleshooting:"
|
||||
echo ""
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " View logs: sudo journalctl -u pulse-host-agent -f"
|
||||
echo " Check status: sudo systemctl status pulse-host-agent"
|
||||
echo " Restart: sudo systemctl restart pulse-host-agent"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " View logs: tail -f $MACOS_LOG_FILE"
|
||||
echo " Check status: launchctl list | grep pulse"
|
||||
echo " Restart: launchctl unload $LAUNCHD_PLIST && launchctl load $LAUNCHD_PLIST"
|
||||
fi
|
||||
echo ""
|
||||
echo " Manual run: $AGENT_PATH --url $PULSE_URL $(if [[ -n "$PULSE_TOKEN" ]]; then echo "--token ***"; fi) --interval $INTERVAL"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
print_footer
|
||||
|
||||
log_info "Service Management Commands:"
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " Start: sudo systemctl start pulse-host-agent"
|
||||
echo " Stop: sudo systemctl stop pulse-host-agent"
|
||||
echo " Restart: sudo systemctl restart pulse-host-agent"
|
||||
echo " Status: sudo systemctl status pulse-host-agent"
|
||||
echo " Logs: sudo journalctl -u pulse-host-agent -f"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " Start: launchctl load $LAUNCHD_PLIST"
|
||||
echo " Stop: launchctl unload $LAUNCHD_PLIST"
|
||||
echo " Restart: launchctl unload $LAUNCHD_PLIST && launchctl load $LAUNCHD_PLIST"
|
||||
echo " Status: launchctl list | grep pulse"
|
||||
echo " Logs: tail -f $MACOS_LOG_FILE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
log_info "Files installed:"
|
||||
echo " Binary: $AGENT_PATH"
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " Service: $SYSTEMD_SERVICE"
|
||||
echo " Logs: $LINUX_LOG_FILE"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " Service: $LAUNCHD_PLIST"
|
||||
echo " Logs: $MACOS_LOG_FILE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
log_info "The agent is now reporting to: $PULSE_URL"
|
||||
echo ""
|
||||
|
||||
log_info "To uninstall, run:"
|
||||
echo " curl -fsSL $PULSE_URL/uninstall-host-agent.sh | bash"
|
||||
echo ""
|
||||
199
frontend-modern/public/uninstall-host-agent.sh
Executable file
199
frontend-modern/public/uninstall-host-agent.sh
Executable file
|
|
@ -0,0 +1,199 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Pulse Host Agent Uninstallation Script
|
||||
# Removes the Pulse host agent and all associated files
|
||||
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RESET='\033[0m'
|
||||
|
||||
# Check if colors are supported
|
||||
if [ -t 1 ] && command -v tput &> /dev/null && [ "$(tput colors)" -ge 8 ]; then
|
||||
USE_COLOR=true
|
||||
else
|
||||
USE_COLOR=false
|
||||
fi
|
||||
|
||||
print_color() {
|
||||
local color="$1"
|
||||
local message="$2"
|
||||
if [ "$USE_COLOR" = true ]; then
|
||||
printf "${color}%s${RESET}\n" "$message"
|
||||
else
|
||||
printf "%s\n" "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
print_color "$GREEN" "✓ $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
print_color "$RED" "✗ $1" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
print_color "$BLUE" "ℹ $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
print_color "$YELLOW" "⚠ $1"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
print_color "$BLUE" " Pulse Host Agent - Uninstallation"
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_footer() {
|
||||
echo ""
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
log_success "Uninstallation complete!"
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# File paths
|
||||
AGENT_PATH="/usr/local/bin/pulse-host-agent"
|
||||
SYSTEMD_SERVICE="/etc/systemd/system/pulse-host-agent.service"
|
||||
LAUNCHD_PLIST="$HOME/Library/LaunchAgents/com.pulse.host-agent.plist"
|
||||
MACOS_LOG_DIR="$HOME/Library/Logs/Pulse"
|
||||
LINUX_LOG_DIR="/var/log/pulse"
|
||||
|
||||
print_header
|
||||
|
||||
# Detect platform
|
||||
case "$(uname -s)" in
|
||||
Linux*)
|
||||
PLATFORM="linux"
|
||||
;;
|
||||
Darwin*)
|
||||
PLATFORM="darwin"
|
||||
;;
|
||||
*)
|
||||
log_error "Unsupported platform: $(uname -s)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Detected platform: $PLATFORM"
|
||||
echo ""
|
||||
|
||||
# Stop and remove systemd service (Linux)
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
if [[ -f "$SYSTEMD_SERVICE" ]] && command -v systemctl &> /dev/null; then
|
||||
log_info "Stopping systemd service..."
|
||||
if sudo systemctl stop pulse-host-agent 2>/dev/null; then
|
||||
log_success "Service stopped"
|
||||
else
|
||||
log_warn "Service was not running or already stopped"
|
||||
fi
|
||||
|
||||
log_info "Disabling systemd service..."
|
||||
sudo systemctl disable pulse-host-agent 2>/dev/null || true
|
||||
|
||||
log_info "Removing systemd service file..."
|
||||
sudo rm -f "$SYSTEMD_SERVICE"
|
||||
sudo systemctl daemon-reload
|
||||
log_success "Systemd service removed"
|
||||
else
|
||||
log_info "Systemd service not found (already removed or never installed)"
|
||||
fi
|
||||
|
||||
# Ensure process is terminated
|
||||
if pgrep -x "pulse-host-agent" > /dev/null; then
|
||||
log_info "Terminating running processes..."
|
||||
sudo pkill -9 "pulse-host-agent" 2>/dev/null || true
|
||||
sleep 1
|
||||
log_success "Processes terminated"
|
||||
fi
|
||||
|
||||
# Remove log directory
|
||||
if [[ -d "$LINUX_LOG_DIR" ]]; then
|
||||
log_info "Removing log directory..."
|
||||
sudo rm -rf "$LINUX_LOG_DIR"
|
||||
log_success "Log directory removed: $LINUX_LOG_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop and remove launchd service (macOS)
|
||||
if [[ "$PLATFORM" == "darwin" ]]; then
|
||||
if [[ -f "$LAUNCHD_PLIST" ]] && command -v launchctl &> /dev/null; then
|
||||
log_info "Unloading launchd service..."
|
||||
if launchctl unload "$LAUNCHD_PLIST" 2>/dev/null; then
|
||||
log_success "Service unloaded"
|
||||
else
|
||||
log_warn "Service was not loaded or already unloaded"
|
||||
fi
|
||||
|
||||
log_info "Removing launchd plist..."
|
||||
rm -f "$LAUNCHD_PLIST"
|
||||
log_success "Launchd service removed"
|
||||
else
|
||||
log_info "Launchd service not found (already removed or never installed)"
|
||||
fi
|
||||
|
||||
# Remove Keychain token
|
||||
log_info "Removing token from macOS Keychain..."
|
||||
if security delete-generic-password -s "pulse-host-agent" -a "$USER" 2>/dev/null; then
|
||||
log_success "Token removed from Keychain"
|
||||
else
|
||||
log_info "Token not found in Keychain (may not have been stored)"
|
||||
fi
|
||||
|
||||
# Remove wrapper script
|
||||
WRAPPER_SCRIPT="/usr/local/bin/pulse-host-agent-wrapper.sh"
|
||||
if [[ -f "$WRAPPER_SCRIPT" ]]; then
|
||||
log_info "Removing wrapper script..."
|
||||
rm -f "$WRAPPER_SCRIPT"
|
||||
log_success "Wrapper script removed"
|
||||
fi
|
||||
|
||||
# Ensure process is terminated
|
||||
if pgrep -x "pulse-host-agent" > /dev/null; then
|
||||
log_info "Terminating running processes..."
|
||||
pkill -9 "pulse-host-agent" 2>/dev/null || true
|
||||
sleep 1
|
||||
log_success "Processes terminated"
|
||||
fi
|
||||
|
||||
# Remove log directory
|
||||
if [[ -d "$MACOS_LOG_DIR" ]]; then
|
||||
log_info "Removing log directory..."
|
||||
rm -rf "$MACOS_LOG_DIR"
|
||||
log_success "Log directory removed: $MACOS_LOG_DIR"
|
||||
fi
|
||||
|
||||
# Remove temporary logs (old location)
|
||||
if [[ -f "/tmp/pulse-host-agent.log" ]]; then
|
||||
log_info "Removing temporary log file..."
|
||||
rm -f /tmp/pulse-host-agent.log
|
||||
log_success "Temporary log removed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove binary
|
||||
if [[ -f "$AGENT_PATH" ]]; then
|
||||
log_info "Removing agent binary..."
|
||||
if sudo rm -f "$AGENT_PATH" 2>/dev/null; then
|
||||
log_success "Agent binary removed: $AGENT_PATH"
|
||||
else
|
||||
log_error "Failed to remove agent binary (permission denied?)"
|
||||
log_info "Try running with sudo: sudo $0"
|
||||
fi
|
||||
else
|
||||
log_info "Agent binary not found: $AGENT_PATH"
|
||||
fi
|
||||
|
||||
print_footer
|
||||
|
||||
log_info "The Pulse Host Agent has been removed from this system."
|
||||
log_info "This host will no longer appear in your Pulse dashboard."
|
||||
echo ""
|
||||
|
|
@ -4,27 +4,60 @@ set -e
|
|||
# Pulse Host Agent Installer
|
||||
# Downloads and installs the Pulse host agent for Linux, macOS, or Windows (WSL)
|
||||
|
||||
trim() {
|
||||
local value="$1"
|
||||
value="${value#"${value%%[![:space:]]*}"}"
|
||||
value="${value%"${value##*[![:space:]]}"}"
|
||||
printf '%s' "$value"
|
||||
}
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RESET='\033[0m'
|
||||
|
||||
log_info() {
|
||||
printf '[INFO] %s\n' "$1"
|
||||
# Check if colors are supported
|
||||
if [ -t 1 ] && command -v tput &> /dev/null && [ "$(tput colors)" -ge 8 ]; then
|
||||
USE_COLOR=true
|
||||
else
|
||||
USE_COLOR=false
|
||||
fi
|
||||
|
||||
print_color() {
|
||||
local color="$1"
|
||||
local message="$2"
|
||||
if [ "$USE_COLOR" = true ]; then
|
||||
printf "${color}%s${RESET}\n" "$message"
|
||||
else
|
||||
printf "%s\n" "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
printf '[ OK ] %s\n' "$1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
printf '[WARN] %s\n' "$1" >&2
|
||||
print_color "$GREEN" "✓ $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
printf '[ERROR] %s\n' "$1" >&2
|
||||
print_color "$RED" "✗ $1" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
print_color "$BLUE" "ℹ $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
print_color "$YELLOW" "⚠ $1"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
print_color "$BLUE" " Pulse Host Agent - Installation"
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_footer() {
|
||||
echo ""
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
log_success "Installation complete!"
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
|
|
@ -66,48 +99,53 @@ done
|
|||
AGENT_PATH="/usr/local/bin/pulse-host-agent"
|
||||
SYSTEMD_SERVICE="/etc/systemd/system/pulse-host-agent.service"
|
||||
LAUNCHD_PLIST="$HOME/Library/LaunchAgents/com.pulse.host-agent.plist"
|
||||
MACOS_LOG_DIR="$HOME/Library/Logs/Pulse"
|
||||
MACOS_LOG_FILE="$MACOS_LOG_DIR/host-agent.log"
|
||||
LINUX_LOG_DIR="/var/log/pulse"
|
||||
LINUX_LOG_FILE="$LINUX_LOG_DIR/host-agent.log"
|
||||
|
||||
# Uninstall function
|
||||
if [[ "$UNINSTALL" == "true" ]]; then
|
||||
log_info "Uninstalling Pulse host agent..."
|
||||
|
||||
# Stop and disable systemd service (Linux)
|
||||
if [[ -f "$SYSTEMD_SERVICE" ]] && command -v systemctl &> /dev/null; then
|
||||
sudo systemctl stop pulse-host-agent 2>/dev/null || true
|
||||
sudo systemctl disable pulse-host-agent 2>/dev/null || true
|
||||
sudo rm -f "$SYSTEMD_SERVICE"
|
||||
sudo systemctl daemon-reload
|
||||
log_success "Removed systemd service"
|
||||
fi
|
||||
|
||||
# Stop and remove launchd service (macOS)
|
||||
if [[ -f "$LAUNCHD_PLIST" ]] && command -v launchctl &> /dev/null; then
|
||||
launchctl unload "$LAUNCHD_PLIST" 2>/dev/null || true
|
||||
rm -f "$LAUNCHD_PLIST"
|
||||
log_success "Removed launchd service"
|
||||
fi
|
||||
|
||||
# Remove binary
|
||||
if [[ -f "$AGENT_PATH" ]]; then
|
||||
sudo rm -f "$AGENT_PATH"
|
||||
log_success "Removed agent binary"
|
||||
fi
|
||||
|
||||
log_success "Pulse host agent uninstalled"
|
||||
exit 0
|
||||
log_warn "The --uninstall flag is deprecated."
|
||||
log_info "Please use the dedicated uninstall script instead:"
|
||||
echo ""
|
||||
echo " curl -fsSL \$PULSE_URL/uninstall-host-agent.sh | bash"
|
||||
echo ""
|
||||
log_info "Or download and run manually:"
|
||||
echo " wget \$PULSE_URL/uninstall-host-agent.sh"
|
||||
echo " chmod +x uninstall-host-agent.sh"
|
||||
echo " ./uninstall-host-agent.sh"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate required parameters for install
|
||||
print_header
|
||||
|
||||
# Interactive prompts if parameters not provided
|
||||
if [[ -z "$PULSE_URL" ]]; then
|
||||
log_error "Missing required parameter: --url"
|
||||
log_info "Interactive Installation Mode"
|
||||
echo ""
|
||||
read -p "Enter Pulse server URL (e.g., http://pulse.example.com:7656): " PULSE_URL
|
||||
PULSE_URL=$(echo "$PULSE_URL" | sed 's:/*$::') # Remove trailing slashes
|
||||
fi
|
||||
|
||||
if [[ -z "$PULSE_URL" ]]; then
|
||||
log_error "Pulse URL is required"
|
||||
echo "Usage: $0 --url <pulse-url> --token <api-token> [--interval 30s] [--platform linux|darwin|windows]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$PULSE_TOKEN" ]] && [[ "$PULSE_TOKEN" != "disabled" ]]; then
|
||||
log_error "Missing required parameter: --token"
|
||||
echo "Usage: $0 --url <pulse-url> --token <api-token> [--interval 30s] [--platform linux|darwin|windows]"
|
||||
exit 1
|
||||
if [[ -z "$PULSE_TOKEN" ]]; then
|
||||
log_warn "No API token provided - agent will attempt to connect without authentication"
|
||||
read -p "Enter API token (or press Enter to skip): " PULSE_TOKEN
|
||||
|
||||
if [[ -z "$PULSE_TOKEN" ]]; then
|
||||
read -p "Continue without token? (y/N): " CONTINUE_WITHOUT_TOKEN
|
||||
if [[ "$CONTINUE_WITHOUT_TOKEN" != "y" ]] && [[ "$CONTINUE_WITHOUT_TOKEN" != "Y" ]]; then
|
||||
log_error "Installation cancelled"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect platform if not specified
|
||||
|
|
@ -147,33 +185,153 @@ case "$ARCH" in
|
|||
;;
|
||||
esac
|
||||
|
||||
log_info "Configuration:"
|
||||
echo " Pulse URL: $PULSE_URL"
|
||||
if [[ -n "$PULSE_TOKEN" ]]; then
|
||||
# Mask token, showing only last 4 characters
|
||||
TOKEN_MASKED="***${PULSE_TOKEN: -4}"
|
||||
echo " Token: $TOKEN_MASKED"
|
||||
else
|
||||
echo " Token: none"
|
||||
fi
|
||||
echo " Interval: $INTERVAL"
|
||||
echo " Platform: $PLATFORM/$ARCH"
|
||||
echo ""
|
||||
|
||||
log_info "Installing Pulse host agent for $PLATFORM/$ARCH..."
|
||||
|
||||
# Check for existing installation and version
|
||||
if [[ -f "$AGENT_PATH" ]]; then
|
||||
log_info "Existing installation detected"
|
||||
CURRENT_VERSION=$("$AGENT_PATH" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "unknown")
|
||||
if [[ "$CURRENT_VERSION" != "unknown" ]]; then
|
||||
echo " Current version: $CURRENT_VERSION"
|
||||
fi
|
||||
|
||||
# Try to get latest version from server
|
||||
if command -v curl &> /dev/null; then
|
||||
LATEST_VERSION=$(curl -fsSL "$PULSE_URL/api/version" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
LATEST_VERSION=$(wget -qO- "$PULSE_URL/api/version" 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' || echo "")
|
||||
fi
|
||||
|
||||
if [[ -n "$LATEST_VERSION" ]] && [[ "$CURRENT_VERSION" != "unknown" ]]; then
|
||||
echo " Latest version: $LATEST_VERSION"
|
||||
if [[ "$CURRENT_VERSION" == "$LATEST_VERSION" ]]; then
|
||||
log_success "Already running latest version"
|
||||
elif [[ "$CURRENT_VERSION" < "$LATEST_VERSION" ]]; then
|
||||
log_info "Update available: $CURRENT_VERSION → $LATEST_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
read -p "Reinstall/update agent? (Y/n): " REINSTALL
|
||||
if [[ "$REINSTALL" == "n" ]] || [[ "$REINSTALL" == "N" ]]; then
|
||||
log_info "Installation cancelled"
|
||||
exit 0
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Download agent binary from Pulse server
|
||||
DOWNLOAD_URL="$PULSE_URL/download/pulse-host-agent?platform=$PLATFORM&arch=$ARCH"
|
||||
TEMP_BINARY="/tmp/pulse-host-agent-$$.tmp"
|
||||
|
||||
log_info "Downloading agent binary from $PULSE_URL..."
|
||||
|
||||
DOWNLOAD_SUCCESS=false
|
||||
CHECKSUM_URL="${DOWNLOAD_URL}.sha256"
|
||||
|
||||
if command -v curl &> /dev/null; then
|
||||
if ! curl -fL --progress-bar -o "$TEMP_BINARY" "$DOWNLOAD_URL"; then
|
||||
log_error "Failed to download agent binary from $DOWNLOAD_URL"
|
||||
log_info "The server may not have prebuilt binaries yet. You can build from source:"
|
||||
log_info " git clone https://github.com/rcourtman/Pulse.git && cd Pulse"
|
||||
log_info " go build -o pulse-host-agent ./cmd/pulse-host-agent"
|
||||
log_info " sudo mv pulse-host-agent /usr/local/bin/"
|
||||
rm -f "$TEMP_BINARY"
|
||||
exit 1
|
||||
if curl -fL --progress-bar -o "$TEMP_BINARY" "$DOWNLOAD_URL" 2>&1; then
|
||||
DOWNLOAD_SUCCESS=true
|
||||
fi
|
||||
# Try to download checksum (optional, server may not provide it yet)
|
||||
EXPECTED_CHECKSUM=$(curl -fsSL "$CHECKSUM_URL" 2>/dev/null || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
if ! wget -q --show-progress -O "$TEMP_BINARY" "$DOWNLOAD_URL"; then
|
||||
log_error "Failed to download agent binary from $DOWNLOAD_URL"
|
||||
rm -f "$TEMP_BINARY"
|
||||
exit 1
|
||||
if wget -q --show-progress -O "$TEMP_BINARY" "$DOWNLOAD_URL" 2>&1; then
|
||||
DOWNLOAD_SUCCESS=true
|
||||
fi
|
||||
# Try to download checksum (optional)
|
||||
EXPECTED_CHECKSUM=$(wget -qO- "$CHECKSUM_URL" 2>/dev/null || echo "")
|
||||
else
|
||||
log_error "Neither curl nor wget found"
|
||||
echo ""
|
||||
log_info "Please install curl or wget to continue:"
|
||||
if [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " brew install curl"
|
||||
elif [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " # Debian/Ubuntu:"
|
||||
echo " sudo apt-get install curl"
|
||||
echo ""
|
||||
echo " # RHEL/CentOS/Fedora:"
|
||||
echo " sudo yum install curl"
|
||||
fi
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$DOWNLOAD_SUCCESS" == false ]]; then
|
||||
log_error "Failed to download agent binary from $DOWNLOAD_URL"
|
||||
echo ""
|
||||
log_info "Troubleshooting steps:"
|
||||
echo ""
|
||||
echo "1. Verify the Pulse server is running:"
|
||||
echo " curl $PULSE_URL/health"
|
||||
echo ""
|
||||
echo "2. Check if the download endpoint is accessible:"
|
||||
echo " curl -I $DOWNLOAD_URL"
|
||||
echo ""
|
||||
echo "3. Build from source as a fallback:"
|
||||
echo " git clone https://github.com/rcourtman/Pulse.git"
|
||||
echo " cd Pulse"
|
||||
echo " go build -o pulse-host-agent ./cmd/pulse-host-agent"
|
||||
echo " sudo mv pulse-host-agent /usr/local/bin/"
|
||||
echo " # Then run this script again with --url and --token"
|
||||
echo ""
|
||||
echo "4. Check firewall/network settings blocking the connection"
|
||||
echo ""
|
||||
rm -f "$TEMP_BINARY"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_success "Downloaded agent binary"
|
||||
|
||||
# Verify checksum if available
|
||||
if [[ -n "$EXPECTED_CHECKSUM" ]]; then
|
||||
log_info "Verifying checksum..."
|
||||
|
||||
if command -v sha256sum &> /dev/null; then
|
||||
ACTUAL_CHECKSUM=$(sha256sum "$TEMP_BINARY" | awk '{print $1}')
|
||||
elif command -v shasum &> /dev/null; then
|
||||
ACTUAL_CHECKSUM=$(shasum -a 256 "$TEMP_BINARY" | awk '{print $1}')
|
||||
else
|
||||
log_warn "No checksum tool found (sha256sum/shasum), skipping verification"
|
||||
ACTUAL_CHECKSUM=""
|
||||
fi
|
||||
|
||||
if [[ -n "$ACTUAL_CHECKSUM" ]]; then
|
||||
# Clean up checksums (remove whitespace, convert to lowercase)
|
||||
EXPECTED_CHECKSUM=$(echo "$EXPECTED_CHECKSUM" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')
|
||||
ACTUAL_CHECKSUM=$(echo "$ACTUAL_CHECKSUM" | tr -d '[:space:]' | tr '[:upper:]' '[:lower:]')
|
||||
|
||||
if [[ "$EXPECTED_CHECKSUM" == "$ACTUAL_CHECKSUM" ]]; then
|
||||
log_success "Checksum verified (SHA256: ${ACTUAL_CHECKSUM:0:16}...)"
|
||||
else
|
||||
log_error "Checksum mismatch!"
|
||||
echo " Expected: $EXPECTED_CHECKSUM"
|
||||
echo " Got: $ACTUAL_CHECKSUM"
|
||||
echo ""
|
||||
log_warn "The downloaded binary may be corrupted or tampered with."
|
||||
read -p "Continue anyway? (y/N): " CONTINUE_ANYWAY
|
||||
if [[ "$CONTINUE_ANYWAY" != "y" ]] && [[ "$CONTINUE_ANYWAY" != "Y" ]]; then
|
||||
rm -f "$TEMP_BINARY"
|
||||
log_error "Installation cancelled"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
log_error "Neither curl nor wget found. Please install one of them."
|
||||
exit 1
|
||||
log_info "Checksum not available (server doesn't provide it yet)"
|
||||
fi
|
||||
|
||||
sudo mv "$TEMP_BINARY" "$AGENT_PATH"
|
||||
|
|
@ -184,6 +342,9 @@ log_success "Agent binary installed to $AGENT_PATH"
|
|||
if [[ "$PLATFORM" == "linux" ]] && command -v systemctl &> /dev/null; then
|
||||
log_info "Setting up systemd service..."
|
||||
|
||||
# Create log directory
|
||||
sudo mkdir -p "$LINUX_LOG_DIR"
|
||||
|
||||
sudo tee "$SYSTEMD_SERVICE" > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Pulse Host Agent
|
||||
|
|
@ -195,11 +356,15 @@ ExecStart=$AGENT_PATH --url $PULSE_URL --token $PULSE_TOKEN --interval $INTERVAL
|
|||
Restart=always
|
||||
RestartSec=5s
|
||||
User=root
|
||||
StandardOutput=append:$LINUX_LOG_FILE
|
||||
StandardError=append:$LINUX_LOG_FILE
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
log_success "Created systemd service configuration"
|
||||
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable pulse-host-agent
|
||||
sudo systemctl start pulse-host-agent
|
||||
|
|
@ -208,9 +373,83 @@ EOF
|
|||
elif [[ "$PLATFORM" == "darwin" ]] && command -v launchctl &> /dev/null; then
|
||||
log_info "Setting up launchd service..."
|
||||
|
||||
# Create log directory
|
||||
mkdir -p "$MACOS_LOG_DIR"
|
||||
mkdir -p "$HOME/Library/LaunchAgents"
|
||||
|
||||
cat > "$LAUNCHD_PLIST" <<EOF
|
||||
# Store token in macOS Keychain for better security
|
||||
if [[ -n "$PULSE_TOKEN" ]]; then
|
||||
log_info "Storing token in macOS Keychain..."
|
||||
|
||||
# Delete existing keychain entry if it exists
|
||||
security delete-generic-password -s "pulse-host-agent" -a "$USER" 2>/dev/null || true
|
||||
|
||||
# Add token to Keychain
|
||||
if security add-generic-password -s "pulse-host-agent" -a "$USER" -w "$PULSE_TOKEN" -U 2>/dev/null; then
|
||||
log_success "Token stored securely in macOS Keychain"
|
||||
USE_KEYCHAIN=true
|
||||
else
|
||||
log_warn "Failed to store token in Keychain, will use plist instead"
|
||||
log_info "You may need to grant Keychain access permissions"
|
||||
USE_KEYCHAIN=false
|
||||
fi
|
||||
else
|
||||
USE_KEYCHAIN=false
|
||||
fi
|
||||
|
||||
# Create wrapper script if using Keychain
|
||||
if [[ "$USE_KEYCHAIN" == true ]]; then
|
||||
WRAPPER_SCRIPT="/usr/local/bin/pulse-host-agent-wrapper.sh"
|
||||
|
||||
cat > "$WRAPPER_SCRIPT" <<'WRAPPER_EOF'
|
||||
#!/bin/bash
|
||||
# Pulse Host Agent Wrapper - Reads token from Keychain
|
||||
set -e
|
||||
|
||||
# Read token from Keychain
|
||||
PULSE_TOKEN=$(security find-generic-password -s "pulse-host-agent" -w 2>/dev/null || echo "")
|
||||
|
||||
# Export for agent to use
|
||||
export PULSE_TOKEN
|
||||
|
||||
# Run the actual agent with all arguments
|
||||
exec /usr/local/bin/pulse-host-agent "$@"
|
||||
WRAPPER_EOF
|
||||
|
||||
chmod +x "$WRAPPER_SCRIPT"
|
||||
log_success "Created Keychain wrapper script"
|
||||
|
||||
# Create plist using wrapper (token not in plist!)
|
||||
cat > "$LAUNCHD_PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.pulse.host-agent</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$WRAPPER_SCRIPT</string>
|
||||
<string>--url</string>
|
||||
<string>$PULSE_URL</string>
|
||||
<string>--interval</string>
|
||||
<string>$INTERVAL</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
log_success "Created launchd service configuration (using Keychain)"
|
||||
else
|
||||
# Create plist with token directly (fallback)
|
||||
cat > "$LAUNCHD_PLIST" <<EOF
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
|
|
@ -232,12 +471,17 @@ elif [[ "$PLATFORM" == "darwin" ]] && command -v launchctl &> /dev/null; then
|
|||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/tmp/pulse-host-agent.log</string>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/tmp/pulse-host-agent.log</string>
|
||||
<string>$MACOS_LOG_FILE</string>
|
||||
</dict>
|
||||
</plist>
|
||||
EOF
|
||||
log_success "Created launchd service configuration"
|
||||
fi
|
||||
|
||||
# Set restrictive permissions on plist
|
||||
chmod 600 "$LAUNCHD_PLIST"
|
||||
|
||||
launchctl load "$LAUNCHD_PLIST"
|
||||
log_success "Launchd service enabled and started"
|
||||
|
|
@ -247,5 +491,115 @@ else
|
|||
log_info " $AGENT_PATH --url $PULSE_URL --token $PULSE_TOKEN --interval $INTERVAL"
|
||||
fi
|
||||
|
||||
log_success "Pulse host agent installation complete!"
|
||||
log_info "The agent is now reporting to $PULSE_URL"
|
||||
# Validate installation
|
||||
log_info "Waiting 10 seconds to validate agent reporting..."
|
||||
sleep 10
|
||||
|
||||
VALIDATION_SUCCESS=false
|
||||
SERVICE_RUNNING=false
|
||||
|
||||
# Check if service is running
|
||||
if [[ "$PLATFORM" == "linux" ]] && command -v systemctl &> /dev/null; then
|
||||
SERVICE_STATUS=$(systemctl is-active pulse-host-agent 2>/dev/null || echo "inactive")
|
||||
if [[ "$SERVICE_STATUS" == "active" ]]; then
|
||||
SERVICE_RUNNING=true
|
||||
log_success "Service is running successfully!"
|
||||
else
|
||||
log_warn "Service status: $SERVICE_STATUS"
|
||||
log_info "Check logs with: sudo journalctl -u pulse-host-agent -n 50"
|
||||
fi
|
||||
elif [[ "$PLATFORM" == "darwin" ]] && command -v launchctl &> /dev/null; then
|
||||
if launchctl list | grep -q "com.pulse.host-agent"; then
|
||||
SERVICE_RUNNING=true
|
||||
log_success "Service is running successfully!"
|
||||
else
|
||||
log_warn "Service may not be running properly"
|
||||
log_info "Check logs with: tail -20 $MACOS_LOG_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Try to verify with API endpoint that agent is reporting
|
||||
if [[ "$SERVICE_RUNNING" == true ]]; then
|
||||
log_info "Verifying agent registration with Pulse server..."
|
||||
|
||||
# Get hostname for verification
|
||||
HOSTNAME=$(hostname)
|
||||
|
||||
# Try to query the API for this host
|
||||
if command -v curl &> /dev/null; then
|
||||
API_CHECK=$(curl -fsSL "$PULSE_URL/api/hosts" 2>/dev/null || echo "")
|
||||
elif command -v wget &> /dev/null; then
|
||||
API_CHECK=$(wget -qO- "$PULSE_URL/api/hosts" 2>/dev/null || echo "")
|
||||
fi
|
||||
|
||||
if [[ -n "$API_CHECK" ]] && echo "$API_CHECK" | grep -q "$HOSTNAME"; then
|
||||
VALIDATION_SUCCESS=true
|
||||
log_success "Agent successfully registered with Pulse server!"
|
||||
log_success "Your host '$HOSTNAME' is now reporting metrics!"
|
||||
elif [[ -n "$API_CHECK" ]]; then
|
||||
log_warn "Agent is running but host not found in API yet (may take a few moments)"
|
||||
log_info "Service appears healthy, metrics should appear shortly."
|
||||
VALIDATION_SUCCESS=true # Service is running, so count as success
|
||||
else
|
||||
log_warn "Could not verify registration via API (endpoint may not be accessible)"
|
||||
log_info "Service is running, check your Pulse dashboard manually."
|
||||
VALIDATION_SUCCESS=true # Service is running, so count as success
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$VALIDATION_SUCCESS" == true ]]; then
|
||||
log_info "Check your Pulse dashboard at: $PULSE_URL"
|
||||
else
|
||||
log_error "Service validation failed"
|
||||
echo ""
|
||||
log_info "Troubleshooting:"
|
||||
echo ""
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " View logs: sudo journalctl -u pulse-host-agent -f"
|
||||
echo " Check status: sudo systemctl status pulse-host-agent"
|
||||
echo " Restart: sudo systemctl restart pulse-host-agent"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " View logs: tail -f $MACOS_LOG_FILE"
|
||||
echo " Check status: launchctl list | grep pulse"
|
||||
echo " Restart: launchctl unload $LAUNCHD_PLIST && launchctl load $LAUNCHD_PLIST"
|
||||
fi
|
||||
echo ""
|
||||
echo " Manual run: $AGENT_PATH --url $PULSE_URL $(if [[ -n "$PULSE_TOKEN" ]]; then echo "--token ***"; fi) --interval $INTERVAL"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
print_footer
|
||||
|
||||
log_info "Service Management Commands:"
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " Start: sudo systemctl start pulse-host-agent"
|
||||
echo " Stop: sudo systemctl stop pulse-host-agent"
|
||||
echo " Restart: sudo systemctl restart pulse-host-agent"
|
||||
echo " Status: sudo systemctl status pulse-host-agent"
|
||||
echo " Logs: sudo journalctl -u pulse-host-agent -f"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " Start: launchctl load $LAUNCHD_PLIST"
|
||||
echo " Stop: launchctl unload $LAUNCHD_PLIST"
|
||||
echo " Restart: launchctl unload $LAUNCHD_PLIST && launchctl load $LAUNCHD_PLIST"
|
||||
echo " Status: launchctl list | grep pulse"
|
||||
echo " Logs: tail -f $MACOS_LOG_FILE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
log_info "Files installed:"
|
||||
echo " Binary: $AGENT_PATH"
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
echo " Service: $SYSTEMD_SERVICE"
|
||||
echo " Logs: $LINUX_LOG_FILE"
|
||||
elif [[ "$PLATFORM" == "darwin" ]]; then
|
||||
echo " Service: $LAUNCHD_PLIST"
|
||||
echo " Logs: $MACOS_LOG_FILE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
log_info "The agent is now reporting to: $PULSE_URL"
|
||||
echo ""
|
||||
|
||||
log_info "To uninstall, run:"
|
||||
echo " curl -fsSL $PULSE_URL/uninstall-host-agent.sh | bash"
|
||||
echo ""
|
||||
|
|
|
|||
199
scripts/uninstall-host-agent.sh
Executable file
199
scripts/uninstall-host-agent.sh
Executable file
|
|
@ -0,0 +1,199 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Pulse Host Agent Uninstallation Script
|
||||
# Removes the Pulse host agent and all associated files
|
||||
|
||||
# ANSI color codes
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RESET='\033[0m'
|
||||
|
||||
# Check if colors are supported
|
||||
if [ -t 1 ] && command -v tput &> /dev/null && [ "$(tput colors)" -ge 8 ]; then
|
||||
USE_COLOR=true
|
||||
else
|
||||
USE_COLOR=false
|
||||
fi
|
||||
|
||||
print_color() {
|
||||
local color="$1"
|
||||
local message="$2"
|
||||
if [ "$USE_COLOR" = true ]; then
|
||||
printf "${color}%s${RESET}\n" "$message"
|
||||
else
|
||||
printf "%s\n" "$message"
|
||||
fi
|
||||
}
|
||||
|
||||
log_success() {
|
||||
print_color "$GREEN" "✓ $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
print_color "$RED" "✗ $1" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
print_color "$BLUE" "ℹ $1"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
print_color "$YELLOW" "⚠ $1"
|
||||
}
|
||||
|
||||
print_header() {
|
||||
echo ""
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
print_color "$BLUE" " Pulse Host Agent - Uninstallation"
|
||||
print_color "$BLUE" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
print_footer() {
|
||||
echo ""
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
log_success "Uninstallation complete!"
|
||||
print_color "$GREEN" "═══════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# File paths
|
||||
AGENT_PATH="/usr/local/bin/pulse-host-agent"
|
||||
SYSTEMD_SERVICE="/etc/systemd/system/pulse-host-agent.service"
|
||||
LAUNCHD_PLIST="$HOME/Library/LaunchAgents/com.pulse.host-agent.plist"
|
||||
MACOS_LOG_DIR="$HOME/Library/Logs/Pulse"
|
||||
LINUX_LOG_DIR="/var/log/pulse"
|
||||
|
||||
print_header
|
||||
|
||||
# Detect platform
|
||||
case "$(uname -s)" in
|
||||
Linux*)
|
||||
PLATFORM="linux"
|
||||
;;
|
||||
Darwin*)
|
||||
PLATFORM="darwin"
|
||||
;;
|
||||
*)
|
||||
log_error "Unsupported platform: $(uname -s)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Detected platform: $PLATFORM"
|
||||
echo ""
|
||||
|
||||
# Stop and remove systemd service (Linux)
|
||||
if [[ "$PLATFORM" == "linux" ]]; then
|
||||
if [[ -f "$SYSTEMD_SERVICE" ]] && command -v systemctl &> /dev/null; then
|
||||
log_info "Stopping systemd service..."
|
||||
if sudo systemctl stop pulse-host-agent 2>/dev/null; then
|
||||
log_success "Service stopped"
|
||||
else
|
||||
log_warn "Service was not running or already stopped"
|
||||
fi
|
||||
|
||||
log_info "Disabling systemd service..."
|
||||
sudo systemctl disable pulse-host-agent 2>/dev/null || true
|
||||
|
||||
log_info "Removing systemd service file..."
|
||||
sudo rm -f "$SYSTEMD_SERVICE"
|
||||
sudo systemctl daemon-reload
|
||||
log_success "Systemd service removed"
|
||||
else
|
||||
log_info "Systemd service not found (already removed or never installed)"
|
||||
fi
|
||||
|
||||
# Ensure process is terminated
|
||||
if pgrep -x "pulse-host-agent" > /dev/null; then
|
||||
log_info "Terminating running processes..."
|
||||
sudo pkill -9 "pulse-host-agent" 2>/dev/null || true
|
||||
sleep 1
|
||||
log_success "Processes terminated"
|
||||
fi
|
||||
|
||||
# Remove log directory
|
||||
if [[ -d "$LINUX_LOG_DIR" ]]; then
|
||||
log_info "Removing log directory..."
|
||||
sudo rm -rf "$LINUX_LOG_DIR"
|
||||
log_success "Log directory removed: $LINUX_LOG_DIR"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Stop and remove launchd service (macOS)
|
||||
if [[ "$PLATFORM" == "darwin" ]]; then
|
||||
if [[ -f "$LAUNCHD_PLIST" ]] && command -v launchctl &> /dev/null; then
|
||||
log_info "Unloading launchd service..."
|
||||
if launchctl unload "$LAUNCHD_PLIST" 2>/dev/null; then
|
||||
log_success "Service unloaded"
|
||||
else
|
||||
log_warn "Service was not loaded or already unloaded"
|
||||
fi
|
||||
|
||||
log_info "Removing launchd plist..."
|
||||
rm -f "$LAUNCHD_PLIST"
|
||||
log_success "Launchd service removed"
|
||||
else
|
||||
log_info "Launchd service not found (already removed or never installed)"
|
||||
fi
|
||||
|
||||
# Remove Keychain token
|
||||
log_info "Removing token from macOS Keychain..."
|
||||
if security delete-generic-password -s "pulse-host-agent" -a "$USER" 2>/dev/null; then
|
||||
log_success "Token removed from Keychain"
|
||||
else
|
||||
log_info "Token not found in Keychain (may not have been stored)"
|
||||
fi
|
||||
|
||||
# Remove wrapper script
|
||||
WRAPPER_SCRIPT="/usr/local/bin/pulse-host-agent-wrapper.sh"
|
||||
if [[ -f "$WRAPPER_SCRIPT" ]]; then
|
||||
log_info "Removing wrapper script..."
|
||||
rm -f "$WRAPPER_SCRIPT"
|
||||
log_success "Wrapper script removed"
|
||||
fi
|
||||
|
||||
# Ensure process is terminated
|
||||
if pgrep -x "pulse-host-agent" > /dev/null; then
|
||||
log_info "Terminating running processes..."
|
||||
pkill -9 "pulse-host-agent" 2>/dev/null || true
|
||||
sleep 1
|
||||
log_success "Processes terminated"
|
||||
fi
|
||||
|
||||
# Remove log directory
|
||||
if [[ -d "$MACOS_LOG_DIR" ]]; then
|
||||
log_info "Removing log directory..."
|
||||
rm -rf "$MACOS_LOG_DIR"
|
||||
log_success "Log directory removed: $MACOS_LOG_DIR"
|
||||
fi
|
||||
|
||||
# Remove temporary logs (old location)
|
||||
if [[ -f "/tmp/pulse-host-agent.log" ]]; then
|
||||
log_info "Removing temporary log file..."
|
||||
rm -f /tmp/pulse-host-agent.log
|
||||
log_success "Temporary log removed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Remove binary
|
||||
if [[ -f "$AGENT_PATH" ]]; then
|
||||
log_info "Removing agent binary..."
|
||||
if sudo rm -f "$AGENT_PATH" 2>/dev/null; then
|
||||
log_success "Agent binary removed: $AGENT_PATH"
|
||||
else
|
||||
log_error "Failed to remove agent binary (permission denied?)"
|
||||
log_info "Try running with sudo: sudo $0"
|
||||
fi
|
||||
else
|
||||
log_info "Agent binary not found: $AGENT_PATH"
|
||||
fi
|
||||
|
||||
print_footer
|
||||
|
||||
log_info "The Pulse Host Agent has been removed from this system."
|
||||
log_info "This host will no longer appear in your Pulse dashboard."
|
||||
echo ""
|
||||
Loading…
Reference in a new issue