242 lines
7.3 KiB
Bash
Executable File
242 lines
7.3 KiB
Bash
Executable File
#! /bin/bash
|
|
|
|
# Color definitions
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Logger functions
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
CURRENT_DIR=$(pwd)
|
|
SERVICE_FILE="haraka.service"
|
|
SERVICE_PATH="/etc/systemd/system/$SERVICE_FILE"
|
|
LOCAL_SERVICE_PATH="$CURRENT_DIR/$SERVICE_FILE"
|
|
|
|
# Load environment variables
|
|
if [ -f "$CURRENT_DIR/.env" ]; then
|
|
export $(cat "$CURRENT_DIR/.env" | grep -v '^#' | xargs)
|
|
else
|
|
log_error ".env file not found"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if MYSQL_ADMIN_PASSWORD is set
|
|
if [ -z "$MYSQL_ADMIN_PASSWORD" ]; then
|
|
log_error "MYSQL_ADMIN_PASSWORD not found in .env file"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -z "$MYSQL_ADMIN_USER" ]; then
|
|
log_error "MYSQL_ADMIN_USER not found in .env file"
|
|
exit 1
|
|
fi
|
|
|
|
# Database configuration
|
|
DB_NAME="email_api1"
|
|
DB_USER="email_api1"
|
|
DB_PASS=$(openssl rand -base64 12) # Generate random password
|
|
|
|
# Check if mysql-server is installed
|
|
if ! command -v mysql &> /dev/null; then
|
|
log_warn "MySQL Server not found. Installing..."
|
|
sudo apt-get update >> /dev/null 2>&1
|
|
sudo apt-get install -y mysql-server >> /dev/null 2>&1
|
|
else
|
|
log_info "MySQL Server is already installed"
|
|
fi
|
|
|
|
# Wait for MySQL to be ready
|
|
log_info "Waiting for MySQL to be ready..."
|
|
while ! mysqladmin ping -h "localhost" -u admin -p"${MYSQL_ADMIN_PASSWORD}" --silent; do
|
|
sleep 1
|
|
done
|
|
|
|
# Create database and user
|
|
log_info "Setting up MySQL database and user..."
|
|
mysql -u admin -p"${MYSQL_ADMIN_PASSWORD}" -e "CREATE DATABASE IF NOT EXISTS ${DB_NAME};"
|
|
|
|
# Check if user exists
|
|
USER_EXISTS=$(mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -s -N -e "SELECT COUNT(*) FROM mysql.user WHERE User = '${DB_USER}' AND Host = 'localhost';")
|
|
|
|
if [ "$USER_EXISTS" -eq 0 ]; then
|
|
log_info "Creating new database user..."
|
|
mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "CREATE USER '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';"
|
|
mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'localhost';"
|
|
mysql -u "${MYSQL_ADMIN_USER}" -p"${MYSQL_ADMIN_PASSWORD}" -e "FLUSH PRIVILEGES;"
|
|
|
|
# Update database config file with new values
|
|
log_info "Updating database configuration..."
|
|
cp "$CURRENT_DIR/src/config/database-example.js" "$CURRENT_DIR/src/config/database.js"
|
|
CONFIG_FILE="$CURRENT_DIR/src/config/database.js"
|
|
sed -i "s/database: \"\"/database: '${DB_NAME}'/" "$CONFIG_FILE"
|
|
sed -i "s/user: \"\"/user: '${DB_USER}'/" "$CONFIG_FILE"
|
|
sed -i "s/password: \"\"/password: '${DB_PASS}'/" "$CONFIG_FILE"
|
|
log_info "Database password has been updated in the configuration file"
|
|
else
|
|
log_warn "Database user already exists. Skipping user creation and configuration update."
|
|
fi
|
|
|
|
# Create group and user
|
|
log_info "Creating group and user..."
|
|
sudo groupadd smtp 2>/dev/null || true
|
|
sudo useradd -r -g smtp smtp 2>/dev/null || true
|
|
|
|
# Create required directories
|
|
log_info "Creating required directories..."
|
|
sudo mkdir -p /var/spool/haraka /var/log/haraka
|
|
sudo chown -R smtp:smtp /var/spool/haraka /var/log/haraka
|
|
|
|
# Set permissions
|
|
log_info "Setting permissions..."
|
|
sudo chmod 755 /var/spool/haraka
|
|
sudo chmod 644 /var/log/haraka
|
|
|
|
# Install Haraka
|
|
log_info "Installing Haraka..."
|
|
if ! command -v haraka &> /dev/null; then
|
|
npm install -g Haraka
|
|
else
|
|
log_warn "Haraka is already installed"
|
|
fi
|
|
|
|
# Check if service file exists and handle accordingly
|
|
log_info "Checking if service file exists..."
|
|
if [ -f "$SERVICE_PATH" ]; then
|
|
# Calculate checksums
|
|
REMOTE_CHECKSUM=$(sha1sum "$SERVICE_PATH" | awk '{print $1}')
|
|
LOCAL_CHECKSUM=$(sha1sum "$LOCAL_SERVICE_PATH" | awk '{print $1}')
|
|
|
|
if [ "$REMOTE_CHECKSUM" != "$LOCAL_CHECKSUM" ]; then
|
|
log_warn "Service file differs from local version. Updating..."
|
|
sudo cp "$LOCAL_SERVICE_PATH" "$SERVICE_PATH"
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable haraka
|
|
sudo systemctl restart haraka
|
|
else
|
|
log_info "Service file is up to date"
|
|
fi
|
|
else
|
|
log_info "Service file not found. Installing..."
|
|
sudo cp "$LOCAL_SERVICE_PATH" "$SERVICE_PATH"
|
|
sudo systemctl daemon-reload
|
|
log_info "Enabling and starting Haraka..."
|
|
sudo systemctl enable haraka
|
|
fi
|
|
|
|
# Install Haraka plugins
|
|
log_info "Installing Haraka plugins..."
|
|
mkdir -p "$CURRENT_DIR/src/email_server/plugins/queue"
|
|
rm -f "$CURRENT_DIR/src/email_server/plugins/queue/store_message.js"
|
|
ln -s "$CURRENT_DIR/src/haraka-plugins/queue/store_message.js" "$CURRENT_DIR/src/email_server/plugins/queue/store_message.js"
|
|
|
|
log_info "Installing dependencies..."
|
|
npm install >> /dev/null 2>&1
|
|
|
|
log_info "Running migrations..."
|
|
npx knex migrate:latest
|
|
|
|
CRON_FILE="$CURRENT_DIR/.cron"
|
|
echo "" > "$CRON_FILE"
|
|
echo "0 * * * * $CURRENT_DIR/scripts/delete_messages_24h.sh >> /var/log/temp_mail/cleanup.log 2>&1" >> "$CRON_FILE"
|
|
echo "0 0 * * * $CURRENT_DIR/scripts/delete_emails_14d.sh >> /var/log/temp_mail/cleanup.log 2>&1" >> "$CRON_FILE"
|
|
|
|
TEMP_CRON="/tmp/temp_cron"
|
|
|
|
mkdir -p /var/log/temp_mail
|
|
|
|
# Check if .cron file exists
|
|
if [ ! -f "$CRON_FILE" ]; then
|
|
log_error "Cron file not found at $CRON_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Function to normalize cron entry (remove extra spaces)
|
|
normalize_cron() {
|
|
echo "$1" | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//' -e 's/[ \t]\+/ /g'
|
|
}
|
|
|
|
# Function to check if a cron job exists
|
|
check_cron_job() {
|
|
local cron_entry="$1"
|
|
local normalized_entry=$(normalize_cron "$cron_entry")
|
|
|
|
# Get current user's crontab
|
|
crontab -l > "$TEMP_CRON" 2>/dev/null
|
|
|
|
# Check if the normalized entry exists in current crontab
|
|
if grep -Fq "$normalized_entry" "$TEMP_CRON"; then
|
|
return 0 # Found
|
|
else
|
|
return 1 # Not found
|
|
fi
|
|
}
|
|
|
|
# Function to install cron jobs
|
|
install_cron_jobs() {
|
|
log_info "Installing cron jobs..."
|
|
|
|
# Get current crontab
|
|
crontab -l > "$TEMP_CRON" 2>/dev/null
|
|
|
|
# Read each line from .cron file
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
# Skip comments and empty lines
|
|
[[ $line =~ ^#.*$ ]] || [ -z "$line" ] && continue
|
|
|
|
normalized_line=$(normalize_cron "$line")
|
|
|
|
if ! grep -Fq "$normalized_line" "$TEMP_CRON"; then
|
|
log_warn "Cron job not found, adding: $normalized_line"
|
|
echo "$normalized_line" >> "$TEMP_CRON"
|
|
else
|
|
log_info "Cron job already exists: $normalized_line"
|
|
fi
|
|
done < "$CRON_FILE"
|
|
|
|
# Install new crontab
|
|
crontab "$TEMP_CRON"
|
|
|
|
# Clean up
|
|
rm -f "$TEMP_CRON"
|
|
}
|
|
|
|
# Main execution
|
|
log_info "Checking cron jobs..."
|
|
|
|
# Read .cron file and check each entry
|
|
missing_jobs=0
|
|
while IFS= read -r line || [ -n "$line" ]; do
|
|
# Skip comments and empty lines
|
|
[[ $line =~ ^#.*$ ]] || [ -z "$line" ] && continue
|
|
|
|
if ! check_cron_job "$line"; then
|
|
log_warn "Missing cron job: $line"
|
|
missing_jobs=$((missing_jobs + 1))
|
|
else
|
|
log_info "Found cron job: $line"
|
|
fi
|
|
done < "$CRON_FILE"
|
|
|
|
# If any jobs are missing, offer to install them
|
|
if [ $missing_jobs -gt 0 ]; then
|
|
log_warn "Found $missing_jobs missing cron job(s)"
|
|
install_cron_jobs
|
|
log_info "Cron jobs have been updated"
|
|
else
|
|
log_info "All cron jobs are up to date"
|
|
fi
|
|
|
|
log_info "Installation complete!"
|
|
log_info "You can now start the email server with: sudo systemctl start haraka" |