Files
desk-moloni/scripts/setup_cron.sh
Emanuel Almeida c19f6fd9ee fix(perfexcrm module): align version to 3.0.1, unify entrypoint, and harden routes/views
- Bump DESK_MOLONI version to 3.0.1 across module
- Normalize hooks to after_client_* and instantiate PerfexHooks safely
- Fix OAuthController view path and API client class name
- Add missing admin views for webhook config/logs; adjust view loading
- Harden client portal routes and admin routes mapping
- Make Dashboard/Logs/Queue tolerant to optional model methods
- Align log details query with existing schema; avoid broken joins

This makes the module operational in Perfex (admin + client), reduces 404s,
and avoids fatal errors due to inconsistent tables/methods.
2025-09-11 17:38:45 +01:00

426 lines
12 KiB
Bash

#!/bin/bash
# Desk-Moloni v3.0 Cron Job Setup Script
#
# Sets up automated cron jobs for queue processing and maintenance tasks.
# Handles different environments and user permissions.
set -euo pipefail
# Script configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MODULE_DIR="$(dirname "$SCRIPT_DIR")"
CLI_DIR="$MODULE_DIR/cli"
LOG_DIR="$MODULE_DIR/logs"
LOCK_DIR="$MODULE_DIR/locks"
# Default configuration
DEFAULT_QUEUE_INTERVAL="*/1" # Every minute
DEFAULT_MAINTENANCE_HOUR="2" # 2 AM
DEFAULT_LOG_RETENTION_DAYS="30"
DEFAULT_USER=""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Help function
show_help() {
cat << EOF
Desk-Moloni v3.0 Cron Setup Script
Usage: $0 [OPTIONS]
Options:
-h, --help Show this help message
-u, --user USER User to run cron jobs as (default: current user)
-i, --interval INTERVAL Queue processor interval (default: */1 for every minute)
-m, --maintenance HOUR Maintenance hour (default: 2 for 2 AM)
-r, --retention DAYS Log retention days (default: 30)
-d, --dry-run Show what would be done without making changes
-v, --verbose Verbose output
--uninstall Remove all cron jobs
--status Show current cron job status
Examples:
$0 # Setup with defaults
$0 -u www-data -i "*/5" # Run as www-data every 5 minutes
$0 --dry-run # Preview changes
$0 --uninstall # Remove all cron jobs
$0 --status # Show current status
Cron Jobs Created:
1. Queue Processor: Processes synchronization queue
2. Daily Maintenance: Cleanup logs, update mappings
3. Health Check: Monitor system health
4. Token Refresh: Refresh OAuth tokens
EOF
}
# Parse command line arguments
QUEUE_INTERVAL="$DEFAULT_QUEUE_INTERVAL"
MAINTENANCE_HOUR="$DEFAULT_MAINTENANCE_HOUR"
LOG_RETENTION_DAYS="$DEFAULT_LOG_RETENTION_DAYS"
CRON_USER="$DEFAULT_USER"
DRY_RUN=false
VERBOSE=false
UNINSTALL=false
SHOW_STATUS=false
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-u|--user)
CRON_USER="$2"
shift 2
;;
-i|--interval)
QUEUE_INTERVAL="$2"
shift 2
;;
-m|--maintenance)
MAINTENANCE_HOUR="$2"
shift 2
;;
-r|--retention)
LOG_RETENTION_DAYS="$2"
shift 2
;;
-d|--dry-run)
DRY_RUN=true
shift
;;
-v|--verbose)
VERBOSE=true
shift
;;
--uninstall)
UNINSTALL=true
shift
;;
--status)
SHOW_STATUS=true
shift
;;
*)
log_error "Unknown option: $1"
show_help
exit 1
;;
esac
done
# Set default user to current user if not specified
if [[ -z "$CRON_USER" ]]; then
CRON_USER=$(whoami)
fi
# Validate user exists
if ! id "$CRON_USER" &>/dev/null; then
log_error "User '$CRON_USER' does not exist"
exit 1
fi
# Check if running as root or target user
CURRENT_USER=$(whoami)
if [[ "$CURRENT_USER" != "root" && "$CURRENT_USER" != "$CRON_USER" ]]; then
log_error "Must run as root or target user ($CRON_USER)"
exit 1
fi
# Validate maintenance hour
if [[ ! "$MAINTENANCE_HOUR" =~ ^[0-9]+$ ]] || [[ "$MAINTENANCE_HOUR" -lt 0 ]] || [[ "$MAINTENANCE_HOUR" -gt 23 ]]; then
log_error "Invalid maintenance hour: $MAINTENANCE_HOUR (must be 0-23)"
exit 1
fi
# Create required directories
create_directories() {
local dirs=("$LOG_DIR" "$LOCK_DIR")
for dir in "${dirs[@]}"; do
if [[ ! -d "$dir" ]]; then
if [[ "$DRY_RUN" == true ]]; then
log_info "Would create directory: $dir"
else
mkdir -p "$dir"
chown "$CRON_USER:$CRON_USER" "$dir" 2>/dev/null || true
log_success "Created directory: $dir"
fi
fi
done
}
# Generate cron job entries
generate_cron_jobs() {
cat << EOF
# Desk-Moloni v3.0 Cron Jobs
# Generated on $(date)
# User: $CRON_USER
# Queue Processor - Process synchronization queue
$QUEUE_INTERVAL * * * * /usr/bin/flock -n $LOCK_DIR/queue_processor.lock php $CLI_DIR/queue_processor.php >> $LOG_DIR/queue_processor.log 2>&1
# Daily Maintenance - Cleanup and optimization
0 $MAINTENANCE_HOUR * * * /usr/bin/flock -n $LOCK_DIR/maintenance.lock $SCRIPT_DIR/maintenance.sh >> $LOG_DIR/maintenance.log 2>&1
# Health Check - System monitoring
*/15 * * * * /usr/bin/flock -n $LOCK_DIR/health_check.lock php $CLI_DIR/sync_commands.php health >> $LOG_DIR/health_check.log 2>&1
# Token Refresh - OAuth token maintenance
0 */6 * * * /usr/bin/flock -n $LOCK_DIR/token_refresh.lock $SCRIPT_DIR/token_refresh.sh >> $LOG_DIR/token_refresh.log 2>&1
# Log Rotation - Cleanup old logs
0 1 * * 0 /usr/bin/find $LOG_DIR -name "*.log" -mtime +$LOG_RETENTION_DAYS -delete
EOF
}
# Get current cron jobs for the user
get_current_crontab() {
if [[ "$CURRENT_USER" == "root" ]]; then
crontab -u "$CRON_USER" -l 2>/dev/null || true
else
crontab -l 2>/dev/null || true
fi
}
# Remove existing Desk-Moloni cron jobs
remove_existing_jobs() {
local current_crontab
current_crontab=$(get_current_crontab)
if [[ -n "$current_crontab" ]]; then
# Remove lines between Desk-Moloni markers
local new_crontab
new_crontab=$(echo "$current_crontab" | sed '/# Desk-Moloni v3.0 Cron Jobs/,/^$/d')
if [[ "$DRY_RUN" == true ]]; then
log_info "Would remove existing Desk-Moloni cron jobs"
else
if [[ "$CURRENT_USER" == "root" ]]; then
echo "$new_crontab" | crontab -u "$CRON_USER" -
else
echo "$new_crontab" | crontab -
fi
log_success "Removed existing Desk-Moloni cron jobs"
fi
return 0
fi
return 1
}
# Install cron jobs
install_cron_jobs() {
local current_crontab new_crontab cron_jobs
current_crontab=$(get_current_crontab)
cron_jobs=$(generate_cron_jobs)
# Combine existing crontab with new jobs
if [[ -n "$current_crontab" ]]; then
new_crontab="$current_crontab"$'\n'"$cron_jobs"
else
new_crontab="$cron_jobs"
fi
if [[ "$DRY_RUN" == true ]]; then
log_info "Would install the following cron jobs:"
echo "$cron_jobs"
else
if [[ "$CURRENT_USER" == "root" ]]; then
echo "$new_crontab" | crontab -u "$CRON_USER" -
else
echo "$new_crontab" | crontab -
fi
log_success "Installed Desk-Moloni cron jobs for user: $CRON_USER"
fi
}
# Show current status
show_status() {
log_info "Desk-Moloni Cron Job Status"
echo "================================"
local current_crontab
current_crontab=$(get_current_crontab)
if [[ -n "$current_crontab" ]]; then
local desk_moloni_jobs
desk_moloni_jobs=$(echo "$current_crontab" | sed -n '/# Desk-Moloni v3.0 Cron Jobs/,/^$/p')
if [[ -n "$desk_moloni_jobs" ]]; then
log_success "Desk-Moloni cron jobs are installed for user: $CRON_USER"
echo "$desk_moloni_jobs"
else
log_warning "No Desk-Moloni cron jobs found for user: $CRON_USER"
fi
else
log_warning "No crontab found for user: $CRON_USER"
fi
# Check if cron daemon is running
if systemctl is-active --quiet cron 2>/dev/null || systemctl is-active --quiet crond 2>/dev/null; then
log_success "Cron daemon is running"
else
log_warning "Cron daemon may not be running"
fi
# Check log files
echo -e "\nLog Files Status:"
for log_file in "queue_processor.log" "maintenance.log" "health_check.log" "token_refresh.log"; do
local log_path="$LOG_DIR/$log_file"
if [[ -f "$log_path" ]]; then
local size=$(du -h "$log_path" | cut -f1)
local modified=$(stat -c %y "$log_path" 2>/dev/null | cut -d' ' -f1,2 | cut -d'.' -f1)
log_info "$log_file: $size (modified: $modified)"
else
log_warning "$log_file: Not found"
fi
done
# Check lock files
echo -e "\nActive Processes:"
for lock_file in "$LOCK_DIR"/*.lock; do
if [[ -f "$lock_file" ]]; then
local lock_name=$(basename "$lock_file" .lock)
log_warning "$lock_name: Process may be running (lock file exists)"
fi
done
}
# Validate PHP and dependencies
validate_dependencies() {
log_info "Validating dependencies..."
# Check PHP
if ! command -v php &> /dev/null; then
log_error "PHP is not installed or not in PATH"
exit 1
fi
local php_version
php_version=$(php -r "echo PHP_VERSION;" 2>/dev/null)
log_success "PHP version: $php_version"
# Check flock
if ! command -v flock &> /dev/null; then
log_error "flock is not installed (required for preventing concurrent execution)"
exit 1
fi
# Check CLI files exist
local cli_files=("$CLI_DIR/queue_processor.php" "$CLI_DIR/sync_commands.php")
for cli_file in "${cli_files[@]}"; do
if [[ ! -f "$cli_file" ]]; then
log_error "CLI file not found: $cli_file"
exit 1
fi
done
log_success "All dependencies validated"
}
# Test cron job syntax
test_cron_syntax() {
log_info "Testing cron job syntax..."
local cron_jobs
cron_jobs=$(generate_cron_jobs)
# Basic validation of cron expressions
while IFS= read -r line; do
if [[ "$line" =~ ^[^#].* ]]; then
local cron_expr
cron_expr=$(echo "$line" | cut -d' ' -f1-5)
# Very basic validation - just check field count
local field_count
field_count=$(echo "$cron_expr" | wc -w)
if [[ "$field_count" -ne 5 ]]; then
log_error "Invalid cron expression: $cron_expr"
exit 1
fi
fi
done <<< "$cron_jobs"
log_success "Cron job syntax validated"
}
# Main execution
main() {
log_info "Desk-Moloni v3.0 Cron Setup"
log_info "User: $CRON_USER"
log_info "Queue Interval: $QUEUE_INTERVAL"
log_info "Maintenance Hour: $MAINTENANCE_HOUR"
if [[ "$DRY_RUN" == true ]]; then
log_warning "DRY RUN MODE - No changes will be made"
fi
if [[ "$SHOW_STATUS" == true ]]; then
show_status
exit 0
fi
if [[ "$UNINSTALL" == true ]]; then
log_info "Uninstalling Desk-Moloni cron jobs..."
if remove_existing_jobs; then
log_success "Cron jobs removed successfully"
else
log_warning "No existing cron jobs found"
fi
exit 0
fi
# Installation process
validate_dependencies
test_cron_syntax
create_directories
# Remove existing jobs first
remove_existing_jobs || true
# Install new jobs
install_cron_jobs
if [[ "$DRY_RUN" == false ]]; then
log_info ""
log_success "Cron jobs have been installed successfully!"
log_info "Monitor logs in: $LOG_DIR"
log_info "Check status with: $0 --status"
log_info ""
log_info "Next steps:"
log_info "1. Verify cron daemon is running: systemctl status cron"
log_info "2. Monitor queue processor: tail -f $LOG_DIR/queue_processor.log"
log_info "3. Check health status: php $CLI_DIR/sync_commands.php health"
fi
}
# Run main function
main "$@"