mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-11-11 09:27:30 +00:00
Compare commits
1 Commits
renovate/v
...
feature/al
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0b028cb77 |
@@ -1,7 +1,32 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
# PatchMon Agent Installation Script
|
||||||
|
# This script requires bash for full functionality
|
||||||
|
# Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | sh
|
||||||
|
|
||||||
|
# Check if bash is available, if not try to install it (for Alpine Linux)
|
||||||
|
if ! command -v bash >/dev/null 2>&1; then
|
||||||
|
if command -v apk >/dev/null 2>&1; then
|
||||||
|
echo "Installing bash for script compatibility..."
|
||||||
|
apk add --no-cache bash >/dev/null 2>&1 || true
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If bash is available and we're not already running in bash, switch to bash
|
||||||
|
# When piped, we can't re-execute easily, so we'll continue with sh
|
||||||
|
# but ensure bash is available for bash-specific features
|
||||||
|
if command -v bash >/dev/null 2>&1 && [ -z "${BASH_VERSION:-}" ]; then
|
||||||
|
# Check if we're being piped (stdin is not a terminal)
|
||||||
|
if [ -t 0 ]; then
|
||||||
|
# Direct execution, re-execute with bash
|
||||||
|
exec bash "$0" "$@"
|
||||||
|
exit $?
|
||||||
|
fi
|
||||||
|
# When piped, we continue with sh but bash is now available
|
||||||
|
# The script will use bash-specific features which should work if bash is installed
|
||||||
|
fi
|
||||||
|
|
||||||
# PatchMon Agent Installation Script
|
# PatchMon Agent Installation Script
|
||||||
# Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | bash
|
# Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
@@ -36,7 +61,7 @@ warning() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check if running as root
|
# Check if running as root
|
||||||
if [[ $EUID -ne 0 ]]; then
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
error "This script must be run as root (use sudo)"
|
error "This script must be run as root (use sudo)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -45,8 +70,8 @@ verify_datetime() {
|
|||||||
info "🕐 Verifying system datetime and timezone..."
|
info "🕐 Verifying system datetime and timezone..."
|
||||||
|
|
||||||
# Get current system time
|
# Get current system time
|
||||||
local system_time=$(date)
|
system_time=$(date)
|
||||||
local timezone=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Unknown")
|
timezone=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Unknown")
|
||||||
|
|
||||||
# Display current datetime info
|
# Display current datetime info
|
||||||
echo ""
|
echo ""
|
||||||
@@ -56,14 +81,17 @@ verify_datetime() {
|
|||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Check if we can read from stdin (interactive terminal)
|
# Check if we can read from stdin (interactive terminal)
|
||||||
if [[ -t 0 ]]; then
|
if [ -t 0 ]; then
|
||||||
# Interactive terminal - ask user
|
# Interactive terminal - ask user
|
||||||
read -p "Does this date/time look correct to you? (y/N): " -r response
|
printf "Does this date/time look correct to you? (y/N): "
|
||||||
if [[ "$response" =~ ^[Yy]$ ]]; then
|
read -r response
|
||||||
success "✅ Date/time verification passed"
|
case "$response" in
|
||||||
echo ""
|
[Yy]*)
|
||||||
return 0
|
success "✅ Date/time verification passed"
|
||||||
else
|
echo ""
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${RED}❌ Date/time verification failed${NC}"
|
echo -e "${RED}❌ Date/time verification failed${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
@@ -72,9 +100,10 @@ verify_datetime() {
|
|||||||
echo " sudo timedatectl set-timezone 'America/New_York' # or your timezone"
|
echo " sudo timedatectl set-timezone 'America/New_York' # or your timezone"
|
||||||
echo " sudo timedatectl list-timezones # to see available timezones"
|
echo " sudo timedatectl list-timezones # to see available timezones"
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${BLUE}ℹ️ After fixing the date/time, re-run this installation script.${NC}"
|
echo -e "${BLUE}ℹ️ After fixing the date/time, re-run this installation script.${NC}"
|
||||||
error "Installation cancelled - please fix date/time and re-run"
|
error "Installation cancelled - please fix date/time and re-run"
|
||||||
fi
|
;;
|
||||||
|
esac
|
||||||
else
|
else
|
||||||
# Non-interactive (piped from curl) - show warning and continue
|
# Non-interactive (piped from curl) - show warning and continue
|
||||||
echo -e "${YELLOW}⚠️ Non-interactive installation detected${NC}"
|
echo -e "${YELLOW}⚠️ Non-interactive installation detected${NC}"
|
||||||
@@ -121,9 +150,9 @@ cleanup_old_files
|
|||||||
# Generate or retrieve machine ID
|
# Generate or retrieve machine ID
|
||||||
get_machine_id() {
|
get_machine_id() {
|
||||||
# Try multiple sources for machine ID
|
# Try multiple sources for machine ID
|
||||||
if [[ -f /etc/machine-id ]]; then
|
if [ -f /etc/machine-id ]; then
|
||||||
cat /etc/machine-id
|
cat /etc/machine-id
|
||||||
elif [[ -f /var/lib/dbus/machine-id ]]; then
|
elif [ -f /var/lib/dbus/machine-id ]; then
|
||||||
cat /var/lib/dbus/machine-id
|
cat /var/lib/dbus/machine-id
|
||||||
else
|
else
|
||||||
# Fallback: generate from hardware info (less ideal but works)
|
# Fallback: generate from hardware info (less ideal but works)
|
||||||
@@ -132,12 +161,12 @@ get_machine_id() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Parse arguments from environment (passed via HTTP headers)
|
# Parse arguments from environment (passed via HTTP headers)
|
||||||
if [[ -z "$PATCHMON_URL" ]] || [[ -z "$API_ID" ]] || [[ -z "$API_KEY" ]]; then
|
if [ -z "$PATCHMON_URL" ] || [ -z "$API_ID" ] || [ -z "$API_KEY" ]; then
|
||||||
error "Missing required parameters. This script should be called via the PatchMon web interface."
|
error "Missing required parameters. This script should be called via the PatchMon web interface."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Auto-detect architecture if not explicitly set
|
# Auto-detect architecture if not explicitly set
|
||||||
if [[ -z "$ARCHITECTURE" ]]; then
|
if [ -z "$ARCHITECTURE" ]; then
|
||||||
arch_raw=$(uname -m 2>/dev/null || echo "unknown")
|
arch_raw=$(uname -m 2>/dev/null || echo "unknown")
|
||||||
|
|
||||||
# Map architecture to supported values
|
# Map architecture to supported values
|
||||||
@@ -162,13 +191,16 @@ if [[ -z "$ARCHITECTURE" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate architecture
|
# Validate architecture
|
||||||
if [[ "$ARCHITECTURE" != "amd64" && "$ARCHITECTURE" != "386" && "$ARCHITECTURE" != "arm64" && "$ARCHITECTURE" != "arm" ]]; then
|
if [ "$ARCHITECTURE" != "amd64" ] && [ "$ARCHITECTURE" != "386" ] && [ "$ARCHITECTURE" != "arm64" ] && [ "$ARCHITECTURE" != "arm" ]; then
|
||||||
error "Invalid architecture '$ARCHITECTURE'. Must be one of: amd64, 386, arm64, arm"
|
error "Invalid architecture '$ARCHITECTURE'. Must be one of: amd64, 386, arm64, arm"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if --force flag is set (for bypassing broken packages)
|
# Check if --force flag is set (for bypassing broken packages)
|
||||||
FORCE_INSTALL="${FORCE_INSTALL:-false}"
|
FORCE_INSTALL="${FORCE_INSTALL:-false}"
|
||||||
if [[ "$*" == *"--force"* ]] || [[ "$FORCE_INSTALL" == "true" ]]; then
|
case "$*" in
|
||||||
|
*"--force"*) FORCE_INSTALL="true" ;;
|
||||||
|
esac
|
||||||
|
if [ "$FORCE_INSTALL" = "true" ]; then
|
||||||
FORCE_INSTALL="true"
|
FORCE_INSTALL="true"
|
||||||
warning "⚠️ Force mode enabled - will bypass broken packages"
|
warning "⚠️ Force mode enabled - will bypass broken packages"
|
||||||
fi
|
fi
|
||||||
@@ -224,7 +256,7 @@ install_apt_packages() {
|
|||||||
# Build apt-get command based on force mode
|
# Build apt-get command based on force mode
|
||||||
local apt_cmd="apt-get install ${missing_packages[*]} -y"
|
local apt_cmd="apt-get install ${missing_packages[*]} -y"
|
||||||
|
|
||||||
if [[ "$FORCE_INSTALL" == "true" ]]; then
|
if [ "$FORCE_INSTALL" = "true" ]; then
|
||||||
info "Using force mode - bypassing broken packages..."
|
info "Using force mode - bypassing broken packages..."
|
||||||
apt_cmd="$apt_cmd -o APT::Get::Fix-Broken=false -o DPkg::Options::=\"--force-confold\" -o DPkg::Options::=\"--force-confdef\""
|
apt_cmd="$apt_cmd -o APT::Get::Fix-Broken=false -o DPkg::Options::=\"--force-confold\" -o DPkg::Options::=\"--force-confdef\""
|
||||||
fi
|
fi
|
||||||
@@ -240,7 +272,7 @@ install_apt_packages() {
|
|||||||
local all_ok=true
|
local all_ok=true
|
||||||
for pkg in "${packages[@]}"; do
|
for pkg in "${packages[@]}"; do
|
||||||
if ! command_exists "$pkg"; then
|
if ! command_exists "$pkg"; then
|
||||||
if [[ "$FORCE_INSTALL" == "true" ]]; then
|
if [ "$FORCE_INSTALL" = "true" ]; then
|
||||||
error "Critical dependency '$pkg' is not available even with --force. Please install manually."
|
error "Critical dependency '$pkg' is not available even with --force. Please install manually."
|
||||||
else
|
else
|
||||||
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apt-get install $pkg"
|
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apt-get install $pkg"
|
||||||
@@ -279,7 +311,7 @@ install_yum_dnf_packages() {
|
|||||||
|
|
||||||
info "Need to install: ${missing_packages[*]}"
|
info "Need to install: ${missing_packages[*]}"
|
||||||
|
|
||||||
if [[ "$pkg_manager" == "yum" ]]; then
|
if [ "$pkg_manager" = "yum" ]; then
|
||||||
yum install -y "${missing_packages[@]}"
|
yum install -y "${missing_packages[@]}"
|
||||||
else
|
else
|
||||||
dnf install -y "${missing_packages[@]}"
|
dnf install -y "${missing_packages[@]}"
|
||||||
@@ -365,7 +397,7 @@ install_apk_packages() {
|
|||||||
local all_ok=true
|
local all_ok=true
|
||||||
for pkg in "${packages[@]}"; do
|
for pkg in "${packages[@]}"; do
|
||||||
if ! command_exists "$pkg"; then
|
if ! command_exists "$pkg"; then
|
||||||
if [[ "$FORCE_INSTALL" == "true" ]]; then
|
if [ "$FORCE_INSTALL" = "true" ]; then
|
||||||
error "Critical dependency '$pkg' is not available even with --force. Please install manually."
|
error "Critical dependency '$pkg' is not available even with --force. Please install manually."
|
||||||
else
|
else
|
||||||
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apk add $pkg"
|
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apk add $pkg"
|
||||||
@@ -391,7 +423,7 @@ if command -v apt-get >/dev/null 2>&1; then
|
|||||||
|
|
||||||
# Check for broken packages
|
# Check for broken packages
|
||||||
if dpkg -l | grep -q "^iH\|^iF" 2>/dev/null; then
|
if dpkg -l | grep -q "^iH\|^iF" 2>/dev/null; then
|
||||||
if [[ "$FORCE_INSTALL" == "true" ]]; then
|
if [ "$FORCE_INSTALL" = "true" ]; then
|
||||||
warning "Detected broken packages on system - force mode will work around them"
|
warning "Detected broken packages on system - force mode will work around them"
|
||||||
else
|
else
|
||||||
warning "⚠️ Broken packages detected on system"
|
warning "⚠️ Broken packages detected on system"
|
||||||
@@ -446,7 +478,7 @@ echo ""
|
|||||||
info "📁 Setting up configuration directory..."
|
info "📁 Setting up configuration directory..."
|
||||||
|
|
||||||
# Check if configuration directory already exists
|
# Check if configuration directory already exists
|
||||||
if [[ -d "/etc/patchmon" ]]; then
|
if [ -d "/etc/patchmon" ]; then
|
||||||
warning "⚠️ Configuration directory already exists at /etc/patchmon"
|
warning "⚠️ Configuration directory already exists at /etc/patchmon"
|
||||||
warning "⚠️ Preserving existing configuration files"
|
warning "⚠️ Preserving existing configuration files"
|
||||||
|
|
||||||
@@ -463,8 +495,8 @@ fi
|
|||||||
# Check if agent is already configured and working (before we overwrite anything)
|
# Check if agent is already configured and working (before we overwrite anything)
|
||||||
info "🔍 Checking if agent is already configured..."
|
info "🔍 Checking if agent is already configured..."
|
||||||
|
|
||||||
if [[ -f /etc/patchmon/config.yml ]] && [[ -f /etc/patchmon/credentials.yml ]]; then
|
if [ -f /etc/patchmon/config.yml ] && [ -f /etc/patchmon/credentials.yml ]; then
|
||||||
if [[ -f /usr/local/bin/patchmon-agent ]]; then
|
if [ -f /usr/local/bin/patchmon-agent ]; then
|
||||||
info "📋 Found existing agent configuration"
|
info "📋 Found existing agent configuration"
|
||||||
info "🧪 Testing existing configuration with ping..."
|
info "🧪 Testing existing configuration with ping..."
|
||||||
|
|
||||||
@@ -495,7 +527,7 @@ fi
|
|||||||
info "🔐 Creating configuration files..."
|
info "🔐 Creating configuration files..."
|
||||||
|
|
||||||
# Check if config file already exists
|
# Check if config file already exists
|
||||||
if [[ -f "/etc/patchmon/config.yml" ]]; then
|
if [ -f "/etc/patchmon/config.yml" ]; then
|
||||||
warning "⚠️ Config file already exists at /etc/patchmon/config.yml"
|
warning "⚠️ Config file already exists at /etc/patchmon/config.yml"
|
||||||
warning "⚠️ Moving existing file out of the way for fresh installation"
|
warning "⚠️ Moving existing file out of the way for fresh installation"
|
||||||
|
|
||||||
@@ -508,7 +540,7 @@ if [[ -f "/etc/patchmon/config.yml" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if credentials file already exists
|
# Check if credentials file already exists
|
||||||
if [[ -f "/etc/patchmon/credentials.yml" ]]; then
|
if [ -f "/etc/patchmon/credentials.yml" ]; then
|
||||||
warning "⚠️ Credentials file already exists at /etc/patchmon/credentials.yml"
|
warning "⚠️ Credentials file already exists at /etc/patchmon/credentials.yml"
|
||||||
warning "⚠️ Moving existing file out of the way for fresh installation"
|
warning "⚠️ Moving existing file out of the way for fresh installation"
|
||||||
|
|
||||||
@@ -521,7 +553,7 @@ if [[ -f "/etc/patchmon/credentials.yml" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean up old credentials file if it exists (from previous installations)
|
# Clean up old credentials file if it exists (from previous installations)
|
||||||
if [[ -f "/etc/patchmon/credentials" ]]; then
|
if [ -f "/etc/patchmon/credentials" ]; then
|
||||||
warning "⚠️ Found old credentials file, removing it..."
|
warning "⚠️ Found old credentials file, removing it..."
|
||||||
rm -f /etc/patchmon/credentials
|
rm -f /etc/patchmon/credentials
|
||||||
info "📋 Removed old credentials file"
|
info "📋 Removed old credentials file"
|
||||||
@@ -557,7 +589,7 @@ info "📥 Downloading PatchMon agent binary..."
|
|||||||
BINARY_NAME="patchmon-agent-linux-${ARCHITECTURE}"
|
BINARY_NAME="patchmon-agent-linux-${ARCHITECTURE}"
|
||||||
|
|
||||||
# Check if agent binary already exists
|
# Check if agent binary already exists
|
||||||
if [[ -f "/usr/local/bin/patchmon-agent" ]]; then
|
if [ -f "/usr/local/bin/patchmon-agent" ]; then
|
||||||
warning "⚠️ Agent binary already exists at /usr/local/bin/patchmon-agent"
|
warning "⚠️ Agent binary already exists at /usr/local/bin/patchmon-agent"
|
||||||
warning "⚠️ Moving existing file out of the way for fresh installation"
|
warning "⚠️ Moving existing file out of the way for fresh installation"
|
||||||
|
|
||||||
@@ -570,7 +602,7 @@ if [[ -f "/usr/local/bin/patchmon-agent" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean up old shell script if it exists (from previous installations)
|
# Clean up old shell script if it exists (from previous installations)
|
||||||
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
|
if [ -f "/usr/local/bin/patchmon-agent.sh" ]; then
|
||||||
warning "⚠️ Found old shell script agent, removing it..."
|
warning "⚠️ Found old shell script agent, removing it..."
|
||||||
rm -f /usr/local/bin/patchmon-agent.sh
|
rm -f /usr/local/bin/patchmon-agent.sh
|
||||||
info "📋 Removed old shell script agent"
|
info "📋 Removed old shell script agent"
|
||||||
@@ -596,7 +628,7 @@ info "📁 Setting up log directory..."
|
|||||||
mkdir -p /etc/patchmon/logs
|
mkdir -p /etc/patchmon/logs
|
||||||
|
|
||||||
# Handle existing log files
|
# Handle existing log files
|
||||||
if [[ -f "/etc/patchmon/logs/patchmon-agent.log" ]]; then
|
if [ -f "/etc/patchmon/logs/patchmon-agent.log" ]; then
|
||||||
warning "⚠️ Existing log file found at /etc/patchmon/logs/patchmon-agent.log"
|
warning "⚠️ Existing log file found at /etc/patchmon/logs/patchmon-agent.log"
|
||||||
warning "⚠️ Rotating log file for fresh start"
|
warning "⚠️ Rotating log file for fresh start"
|
||||||
|
|
||||||
@@ -613,23 +645,26 @@ else
|
|||||||
error "❌ Failed to validate API credentials or reach server"
|
error "❌ Failed to validate API credentials or reach server"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Step 5: Setup systemd service for WebSocket connection
|
# Step 5: Setup service for WebSocket connection
|
||||||
# Note: The service will automatically send an initial report on startup (see serve.go)
|
# Note: The service will automatically send an initial report on startup (see serve.go)
|
||||||
info "🔧 Setting up systemd service..."
|
# Detect init system and create appropriate service
|
||||||
|
if command -v systemctl >/dev/null 2>&1; then
|
||||||
|
# Systemd is available
|
||||||
|
info "🔧 Setting up systemd service..."
|
||||||
|
|
||||||
# Stop and disable existing service if it exists
|
# Stop and disable existing service if it exists
|
||||||
if systemctl is-active --quiet patchmon-agent.service 2>/dev/null; then
|
if systemctl is-active --quiet patchmon-agent.service 2>/dev/null; then
|
||||||
warning "⚠️ Stopping existing PatchMon agent service..."
|
warning "⚠️ Stopping existing PatchMon agent service..."
|
||||||
systemctl stop patchmon-agent.service
|
systemctl stop patchmon-agent.service
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if systemctl is-enabled --quiet patchmon-agent.service 2>/dev/null; then
|
if systemctl is-enabled --quiet patchmon-agent.service 2>/dev/null; then
|
||||||
warning "⚠️ Disabling existing PatchMon agent service..."
|
warning "⚠️ Disabling existing PatchMon agent service..."
|
||||||
systemctl disable patchmon-agent.service
|
systemctl disable patchmon-agent.service
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create systemd service file
|
# Create systemd service file
|
||||||
cat > /etc/systemd/system/patchmon-agent.service << EOF
|
cat > /etc/systemd/system/patchmon-agent.service << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=PatchMon Agent Service
|
Description=PatchMon Agent Service
|
||||||
After=network.target
|
After=network.target
|
||||||
@@ -652,24 +687,104 @@ SyslogIdentifier=patchmon-agent
|
|||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Clean up old crontab entries if they exist (from previous installations)
|
# Clean up old crontab entries if they exist (from previous installations)
|
||||||
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
|
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
|
||||||
warning "⚠️ Found old crontab entries, removing them..."
|
warning "⚠️ Found old crontab entries, removing them..."
|
||||||
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
|
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
|
||||||
info "📋 Removed old crontab entries"
|
info "📋 Removed old crontab entries"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Reload systemd and enable/start the service
|
# Reload systemd and enable/start the service
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable patchmon-agent.service
|
systemctl enable patchmon-agent.service
|
||||||
systemctl start patchmon-agent.service
|
systemctl start patchmon-agent.service
|
||||||
|
|
||||||
# Check if service started successfully
|
# Check if service started successfully
|
||||||
if systemctl is-active --quiet patchmon-agent.service; then
|
if systemctl is-active --quiet patchmon-agent.service; then
|
||||||
success "✅ PatchMon Agent service started successfully"
|
success "✅ PatchMon Agent service started successfully"
|
||||||
info "🔗 WebSocket connection established"
|
info "🔗 WebSocket connection established"
|
||||||
|
else
|
||||||
|
warning "⚠️ Service may have failed to start. Check status with: systemctl status patchmon-agent"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SERVICE_TYPE="systemd"
|
||||||
|
elif [ -d /etc/init.d ] && command -v rc-service >/dev/null 2>&1; then
|
||||||
|
# OpenRC is available (Alpine Linux)
|
||||||
|
info "🔧 Setting up OpenRC service..."
|
||||||
|
|
||||||
|
# Stop and disable existing service if it exists
|
||||||
|
if rc-service patchmon-agent status >/dev/null 2>&1; then
|
||||||
|
warning "⚠️ Stopping existing PatchMon agent service..."
|
||||||
|
rc-service patchmon-agent stop
|
||||||
|
fi
|
||||||
|
|
||||||
|
if rc-update show default 2>/dev/null | grep -q "patchmon-agent"; then
|
||||||
|
warning "⚠️ Disabling existing PatchMon agent service..."
|
||||||
|
rc-update del patchmon-agent default
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create OpenRC service file
|
||||||
|
cat > /etc/init.d/patchmon-agent << 'EOF'
|
||||||
|
#!/sbin/openrc-run
|
||||||
|
|
||||||
|
name="patchmon-agent"
|
||||||
|
description="PatchMon Agent Service"
|
||||||
|
command="/usr/local/bin/patchmon-agent"
|
||||||
|
command_args="serve"
|
||||||
|
command_user="root"
|
||||||
|
pidfile="/var/run/patchmon-agent.pid"
|
||||||
|
command_background="yes"
|
||||||
|
working_dir="/etc/patchmon"
|
||||||
|
|
||||||
|
depend() {
|
||||||
|
need net
|
||||||
|
after net
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x /etc/init.d/patchmon-agent
|
||||||
|
|
||||||
|
# Clean up old crontab entries if they exist (from previous installations)
|
||||||
|
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
|
||||||
|
warning "⚠️ Found old crontab entries, removing them..."
|
||||||
|
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
|
||||||
|
info "📋 Removed old crontab entries"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Enable and start the service
|
||||||
|
rc-update add patchmon-agent default
|
||||||
|
rc-service patchmon-agent start
|
||||||
|
|
||||||
|
# Check if service started successfully
|
||||||
|
if rc-service patchmon-agent status >/dev/null 2>&1; then
|
||||||
|
success "✅ PatchMon Agent service started successfully"
|
||||||
|
info "🔗 WebSocket connection established"
|
||||||
|
else
|
||||||
|
warning "⚠️ Service may have failed to start. Check status with: rc-service patchmon-agent status"
|
||||||
|
fi
|
||||||
|
|
||||||
|
SERVICE_TYPE="openrc"
|
||||||
else
|
else
|
||||||
warning "⚠️ Service may have failed to start. Check status with: systemctl status patchmon-agent"
|
# No init system detected, use crontab as fallback
|
||||||
|
warning "⚠️ No init system detected (systemd or OpenRC). Using crontab for service management."
|
||||||
|
|
||||||
|
# Clean up old crontab entries if they exist
|
||||||
|
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
|
||||||
|
warning "⚠️ Found old crontab entries, removing them..."
|
||||||
|
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
|
||||||
|
info "📋 Removed old crontab entries"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add crontab entry to run the agent
|
||||||
|
(crontab -l 2>/dev/null; echo "@reboot /usr/local/bin/patchmon-agent serve >/dev/null 2>&1") | crontab -
|
||||||
|
info "📋 Added crontab entry for PatchMon agent"
|
||||||
|
|
||||||
|
# Start the agent manually
|
||||||
|
/usr/local/bin/patchmon-agent serve >/dev/null 2>&1 &
|
||||||
|
success "✅ PatchMon Agent started in background"
|
||||||
|
info "🔗 WebSocket connection established"
|
||||||
|
|
||||||
|
SERVICE_TYPE="crontab"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Installation complete
|
# Installation complete
|
||||||
@@ -680,14 +795,20 @@ echo " • Configuration directory: /etc/patchmon"
|
|||||||
echo " • Agent binary installed: /usr/local/bin/patchmon-agent"
|
echo " • Agent binary installed: /usr/local/bin/patchmon-agent"
|
||||||
echo " • Architecture: $ARCHITECTURE"
|
echo " • Architecture: $ARCHITECTURE"
|
||||||
echo " • Dependencies installed: jq, curl, bc"
|
echo " • Dependencies installed: jq, curl, bc"
|
||||||
echo " • Systemd service configured and running"
|
if [ "$SERVICE_TYPE" = "systemd" ]; then
|
||||||
|
echo " • Systemd service configured and running"
|
||||||
|
elif [ "$SERVICE_TYPE" = "openrc" ]; then
|
||||||
|
echo " • OpenRC service configured and running"
|
||||||
|
else
|
||||||
|
echo " • Service configured via crontab"
|
||||||
|
fi
|
||||||
echo " • API credentials configured and tested"
|
echo " • API credentials configured and tested"
|
||||||
echo " • WebSocket connection established"
|
echo " • WebSocket connection established"
|
||||||
echo " • Logs directory: /etc/patchmon/logs"
|
echo " • Logs directory: /etc/patchmon/logs"
|
||||||
|
|
||||||
# Check for moved files and show them
|
# Check for moved files and show them
|
||||||
MOVED_FILES=$(ls /etc/patchmon/credentials.yml.backup.* /etc/patchmon/config.yml.backup.* /usr/local/bin/patchmon-agent.backup.* /etc/patchmon/logs/patchmon-agent.log.old.* /usr/local/bin/patchmon-agent.sh.backup.* /etc/patchmon/credentials.backup.* 2>/dev/null || true)
|
MOVED_FILES=$(ls /etc/patchmon/credentials.yml.backup.* /etc/patchmon/config.yml.backup.* /usr/local/bin/patchmon-agent.backup.* /etc/patchmon/logs/patchmon-agent.log.old.* /usr/local/bin/patchmon-agent.sh.backup.* /etc/patchmon/credentials.backup.* 2>/dev/null || true)
|
||||||
if [[ -n "$MOVED_FILES" ]]; then
|
if [ -n "$MOVED_FILES" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}"
|
echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}"
|
||||||
echo "$MOVED_FILES" | while read -r moved_file; do
|
echo "$MOVED_FILES" | while read -r moved_file; do
|
||||||
@@ -702,8 +823,17 @@ echo -e "${BLUE}🔧 Management Commands:${NC}"
|
|||||||
echo " • Test connection: /usr/local/bin/patchmon-agent ping"
|
echo " • Test connection: /usr/local/bin/patchmon-agent ping"
|
||||||
echo " • Manual report: /usr/local/bin/patchmon-agent report"
|
echo " • Manual report: /usr/local/bin/patchmon-agent report"
|
||||||
echo " • Check status: /usr/local/bin/patchmon-agent diagnostics"
|
echo " • Check status: /usr/local/bin/patchmon-agent diagnostics"
|
||||||
echo " • Service status: systemctl status patchmon-agent"
|
if [ "$SERVICE_TYPE" = "systemd" ]; then
|
||||||
echo " • Service logs: journalctl -u patchmon-agent -f"
|
echo " • Service status: systemctl status patchmon-agent"
|
||||||
echo " • Restart service: systemctl restart patchmon-agent"
|
echo " • Service logs: journalctl -u patchmon-agent -f"
|
||||||
|
echo " • Restart service: systemctl restart patchmon-agent"
|
||||||
|
elif [ "$SERVICE_TYPE" = "openrc" ]; then
|
||||||
|
echo " • Service status: rc-service patchmon-agent status"
|
||||||
|
echo " • Service logs: tail -f /etc/patchmon/logs/patchmon-agent.log"
|
||||||
|
echo " • Restart service: rc-service patchmon-agent restart"
|
||||||
|
else
|
||||||
|
echo " • Service logs: tail -f /etc/patchmon/logs/patchmon-agent.log"
|
||||||
|
echo " • Restart service: pkill -f 'patchmon-agent serve' && /usr/local/bin/patchmon-agent serve &"
|
||||||
|
fi
|
||||||
echo ""
|
echo ""
|
||||||
success "✅ Your system is now being monitored by PatchMon!"
|
success "✅ Your system is now being monitored by PatchMon!"
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.3.14",
|
"@types/react": "^18.3.14",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"@vitejs/plugin-react": "^5.0.0",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
|
|||||||
170
package-lock.json
generated
170
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "patchmon",
|
"name": "patchmon",
|
||||||
"version": "1.3.3",
|
"version": "1.3.2",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "patchmon",
|
"name": "patchmon",
|
||||||
"version": "1.3.3",
|
"version": "1.3.2",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"backend",
|
"backend",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"backend": {
|
"backend": {
|
||||||
"name": "patchmon-backend",
|
"name": "patchmon-backend",
|
||||||
"version": "1.3.3",
|
"version": "1.3.2",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bull-board/api": "^6.13.1",
|
"@bull-board/api": "^6.13.1",
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
},
|
},
|
||||||
"frontend": {
|
"frontend": {
|
||||||
"name": "patchmon-frontend",
|
"name": "patchmon-frontend",
|
||||||
"version": "1.3.3",
|
"version": "1.3.2",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.3.14",
|
"@types/react": "^18.3.14",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"@vitejs/plugin-react": "^5.0.0",
|
"@vitejs/plugin-react": "^4.3.4",
|
||||||
"autoprefixer": "^10.4.20",
|
"autoprefixer": "^10.4.20",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
@@ -134,7 +134,6 @@
|
|||||||
"version": "7.28.4",
|
"version": "7.28.4",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.27.1",
|
"@babel/code-frame": "^7.27.1",
|
||||||
"@babel/generator": "^7.28.3",
|
"@babel/generator": "^7.28.3",
|
||||||
@@ -548,7 +547,6 @@
|
|||||||
"node_modules/@bull-board/ui": {
|
"node_modules/@bull-board/ui": {
|
||||||
"version": "6.13.1",
|
"version": "6.13.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@bull-board/api": "6.13.1"
|
"@bull-board/api": "6.13.1"
|
||||||
}
|
}
|
||||||
@@ -582,7 +580,6 @@
|
|||||||
"node_modules/@dnd-kit/core": {
|
"node_modules/@dnd-kit/core": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dnd-kit/accessibility": "^3.1.1",
|
"@dnd-kit/accessibility": "^3.1.1",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
@@ -898,9 +895,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/pluginutils": {
|
"node_modules/@rolldown/pluginutils": {
|
||||||
"version": "1.0.0-beta.43",
|
"version": "1.0.0-beta.27",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.43.tgz",
|
|
||||||
"integrity": "sha512-5Uxg7fQUCmfhax7FJke2+8B6cqgeUJUD9o2uXIKXhD+mG0mL6NObmVoi9wXEU1tY89mZKgAYA6fTbftx3q2ZPQ==",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -1025,7 +1020,6 @@
|
|||||||
"version": "18.3.24",
|
"version": "18.3.24",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
@@ -1044,21 +1038,19 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@vitejs/plugin-react": {
|
"node_modules/@vitejs/plugin-react": {
|
||||||
"version": "5.1.0",
|
"version": "4.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-4LuWrg7EKWgQaMJfnN+wcmbAW+VSsCmqGohftWjuct47bv8uE4n/nPpq4XjJPsxgq00GGG5J8dvBczp8uxScew==",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.28.4",
|
"@babel/core": "^7.28.0",
|
||||||
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
|
"@babel/plugin-transform-react-jsx-self": "^7.27.1",
|
||||||
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
|
"@babel/plugin-transform-react-jsx-source": "^7.27.1",
|
||||||
"@rolldown/pluginutils": "1.0.0-beta.43",
|
"@rolldown/pluginutils": "1.0.0-beta.27",
|
||||||
"@types/babel__core": "^7.20.5",
|
"@types/babel__core": "^7.20.5",
|
||||||
"react-refresh": "^0.18.0"
|
"react-refresh": "^0.17.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^14.18.0 || >=16.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||||
@@ -1275,7 +1267,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.8.3",
|
"baseline-browser-mapping": "^2.8.3",
|
||||||
"caniuse-lite": "^1.0.30001741",
|
"caniuse-lite": "^1.0.30001741",
|
||||||
@@ -1465,7 +1456,6 @@
|
|||||||
"node_modules/chart.js": {
|
"node_modules/chart.js": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kurkle/color": "^0.3.0"
|
"@kurkle/color": "^0.3.0"
|
||||||
},
|
},
|
||||||
@@ -2040,7 +2030,6 @@
|
|||||||
"node_modules/express": {
|
"node_modules/express": {
|
||||||
"version": "4.21.2",
|
"version": "4.21.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"accepts": "~1.3.8",
|
"accepts": "~1.3.8",
|
||||||
"array-flatten": "1.1.1",
|
"array-flatten": "1.1.1",
|
||||||
@@ -2806,76 +2795,6 @@
|
|||||||
"lefthook-windows-x64": "1.13.5"
|
"lefthook-windows-x64": "1.13.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lefthook-darwin-arm64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-BYt5CnAOXasVCS6i+A4ljUo9xru/B5uMFD6EWHhs3R26jGF7mBSDxM3ErzXTUaJRTP0kQI/XBmgqBryBqoqZOQ==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-darwin-x64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-ZDtLBzvI5e26C/RZ4irOHpELTd22x9lDTgF2+eCYcnrBWOkB7800V8tuAvBybsLGvg6JwKjFxn+NTRNZnCC2hw==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"darwin"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-freebsd-arm64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-uQ/kQZSSedw74aGCpsfOPN4yVt3klg8grOP6gHQOCRUMv5oK/Lj3pe1PylpTuuhxWORWRzkauPMot26J0OZZdA==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"freebsd"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-freebsd-x64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-6czek8XagVrI7ExURawkfrfX40Qjc/wktc8bLq/iXfRlmdvKDMrx2FrA82mDfEVCAEz+tTvkteK1TfR3icYF3Q==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"freebsd"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-linux-arm64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-MjWtiuW1br+rpTtgG1KGV53mSGtL5MWQwgafYzrFleJ89fKb86F4TD/4mVNzk5thmZ+HVPZw9bRZGUHFBnNJWg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"linux"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-linux-x64": {
|
"node_modules/lefthook-linux-x64": {
|
||||||
"version": "1.13.5",
|
"version": "1.13.5",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
@@ -2888,62 +2807,6 @@
|
|||||||
"linux"
|
"linux"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/lefthook-openbsd-arm64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-lYXrWf0/hBrwtG8ceaHq886bcqRKh3Lfv+jZJs+ykMLB6L/kaqk8tA4V2NHWydQ5h56o45ugs/580nMz36ZdRg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"openbsd"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-openbsd-x64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-Ba1JrsRbfan4WKd8Q7gUhTxCUuppXzirDObd3JxpLRSLxA47yxhjMv7KByDunRDTvzTgsXoykZI6mPupkc1JiQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"openbsd"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-windows-arm64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-Y/CpmEIb0hlFe+kTT/efWgX6+/gUTp5NItTF+gmUrY1/G/bTLIxdIRS7WpodVM0MEN24sOrQVTSi9DN9FvGoGg==",
|
|
||||||
"cpu": [
|
|
||||||
"arm64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lefthook-windows-x64": {
|
|
||||||
"version": "1.13.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.13.5.tgz",
|
|
||||||
"integrity": "sha512-WJBqGNBlFJnunRwy12QyaDHdGULtostPqpYSZSS4boFJDY0lP5qtz9lAGmJ49aA5GQ19jrnDjGLwVPFiwIqksQ==",
|
|
||||||
"cpu": [
|
|
||||||
"x64"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"os": [
|
|
||||||
"win32"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"node_modules/lilconfig": {
|
"node_modules/lilconfig": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@@ -3556,7 +3419,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.11",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
@@ -3686,7 +3548,6 @@
|
|||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/config": "6.16.2",
|
"@prisma/config": "6.16.2",
|
||||||
"@prisma/engines": "6.16.2"
|
"@prisma/engines": "6.16.2"
|
||||||
@@ -3876,7 +3737,6 @@
|
|||||||
"node_modules/react": {
|
"node_modules/react": {
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
},
|
},
|
||||||
@@ -3895,7 +3755,6 @@
|
|||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
@@ -3912,9 +3771,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.18.0",
|
"version": "0.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz",
|
|
||||||
"integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==",
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -4615,7 +4472,6 @@
|
|||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@@ -4768,7 +4624,6 @@
|
|||||||
"version": "7.1.7",
|
"version": "7.1.7",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.5.0",
|
"fdir": "^6.5.0",
|
||||||
@@ -4858,7 +4713,6 @@
|
|||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user