Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cb3079a7ae | |||
| 5a7e79d8c4 | |||
| d60cb62d8f |
Executable
+160
@@ -0,0 +1,160 @@
|
||||
#!/bin/bash
|
||||
# =============================================================================
|
||||
# migrate_markasjunk2_to_markasjunk.sh
|
||||
#
|
||||
# Migrates the external roundcube-markasjunk2 plugin to the built-in
|
||||
# markasjunk plugin included in Roundcube 1.7.x+
|
||||
#
|
||||
# Usage: migrate_markasjunk2_to_markasjunk.sh <roundcube-install-dir>
|
||||
#
|
||||
# Example:
|
||||
# migrate_markasjunk2_to_markasjunk.sh /var/www/webmail/roundcubemail-1.7.1
|
||||
# =============================================================================
|
||||
|
||||
RC_DIR="${1}"
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Colors / output helpers
|
||||
# -----------------------------------------------------------------------------
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
yellow='\033[1;33m'
|
||||
cyan='\033[0;36m'
|
||||
reset='\033[0m'
|
||||
|
||||
info() { echo -e "${cyan}[INFO]${reset} $*"; }
|
||||
ok() { echo -e "${green}[OK]${reset} $*"; }
|
||||
skip() { echo -e "\033[0;37m[SKIP] $*${reset}"; }
|
||||
warn() { echo -e "${yellow}[WARN]${reset} $*"; }
|
||||
error() { echo -e "${red}[ERROR]${reset} $*"; }
|
||||
#fatal() { echo -e "${red}[FATAL]${reset} $*"; exit 1; }
|
||||
fatal() { echo -e "\n ${red}[FATAL]${reset} $*\n"; exit 1; }
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Sanity checks
|
||||
# -----------------------------------------------------------------------------
|
||||
[[ -z "$RC_DIR" ]] && fatal "Usage: $0 <roundcube-install-dir>"
|
||||
[[ -d "$RC_DIR" ]] || fatal "Directory not found: $RC_DIR"
|
||||
|
||||
RC_CONFIG="${RC_DIR}/config/config.inc.php"
|
||||
PLUGIN_DIR_NEW="${RC_DIR}/plugins/markasjunk"
|
||||
PLUGIN_CONFIG_NEW="${PLUGIN_DIR_NEW}/config.inc.php"
|
||||
|
||||
[[ -f "$RC_CONFIG" ]] || fatal "Roundcube config not found: $RC_CONFIG"
|
||||
[[ -d "$PLUGIN_DIR_NEW" ]] || fatal "Built-in markasjunk plugin not found: ${PLUGIN_DIR_NEW}"
|
||||
|
||||
echo ""
|
||||
echo "================================================================="
|
||||
echo " Migrate markasjunk2 -> markasjunk"
|
||||
echo " Roundcube: ${RC_DIR}"
|
||||
echo "================================================================="
|
||||
echo ""
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Find markasjunk2 plugin directory (may have different names)
|
||||
# -----------------------------------------------------------------------------
|
||||
PLUGIN_DIR_OLD=""
|
||||
for candidate in \
|
||||
"${RC_DIR}/plugins/markasjunk2" \
|
||||
"${RC_DIR}/plugins/roundcube-markasjunk2-master" \
|
||||
"${RC_DIR}/plugins/roundcube-markasjunk2" ; do
|
||||
if [[ -d "$candidate" ]]; then
|
||||
PLUGIN_DIR_OLD="$candidate"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
PLUGIN_CONFIG_OLD=""
|
||||
if [[ -n "$PLUGIN_DIR_OLD" ]]; then
|
||||
if [[ -f "${PLUGIN_DIR_OLD}/config.inc.php" ]]; then
|
||||
PLUGIN_CONFIG_OLD="${PLUGIN_DIR_OLD}/config.inc.php"
|
||||
elif [[ -f "${PLUGIN_DIR_OLD}/config.inc.php.dist" ]]; then
|
||||
PLUGIN_CONFIG_OLD="${PLUGIN_DIR_OLD}/config.inc.php.dist"
|
||||
warn "No config.inc.php found in markasjunk2 plugin, using .dist file"
|
||||
fi
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Step 1: Replace plugin name in Roundcube config
|
||||
# -----------------------------------------------------------------------------
|
||||
info "Step 1: Replacing 'markasjunk2' with 'markasjunk' in config.inc.php.."
|
||||
|
||||
if grep -q "'markasjunk2'" "$RC_CONFIG" ; then
|
||||
sed -i "s/'markasjunk2'/'markasjunk'/g" "$RC_CONFIG"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
ok "Plugin name updated in ${RC_CONFIG}"
|
||||
else
|
||||
fatal "Failed to update plugin name in ${RC_CONFIG}"
|
||||
fi
|
||||
elif grep -q "'markasjunk'" "$RC_CONFIG" ; then
|
||||
skip "Plugin 'markasjunk' already active in config"
|
||||
else
|
||||
warn "Neither 'markasjunk2' nor 'markasjunk' found in config – please check manually"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Step 2: Migrate plugin config (markasjunk2_ -> markasjunk_)
|
||||
# -----------------------------------------------------------------------------
|
||||
info "Step 2: Migrating plugin config.."
|
||||
|
||||
if [[ -f "$PLUGIN_CONFIG_NEW" ]]; then
|
||||
skip "markasjunk config already exists: ${PLUGIN_CONFIG_NEW}"
|
||||
elif [[ -n "$PLUGIN_CONFIG_OLD" ]]; then
|
||||
info "Source config: ${PLUGIN_CONFIG_OLD}"
|
||||
|
||||
# Copy and rename all markasjunk2_ keys to markasjunk_
|
||||
sed "s/markasjunk2_/markasjunk_/g" "$PLUGIN_CONFIG_OLD" > "$PLUGIN_CONFIG_NEW"
|
||||
|
||||
if [[ $? -eq 0 ]]; then
|
||||
ok "Config migrated to ${PLUGIN_CONFIG_NEW}"
|
||||
info "Key changes applied: markasjunk2_* -> markasjunk_*"
|
||||
else
|
||||
fatal "Failed to write ${PLUGIN_CONFIG_NEW}"
|
||||
fi
|
||||
else
|
||||
warn "No markasjunk2 config found – using built-in defaults for markasjunk"
|
||||
info "Defaults are fine if your markasjunk2 config was unmodified"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Step 3: Optionally remove old markasjunk2 plugin directory
|
||||
# -----------------------------------------------------------------------------
|
||||
if [[ -n "$PLUGIN_DIR_OLD" ]]; then
|
||||
echo ""
|
||||
echo -n "Remove old markasjunk2 plugin directory '${PLUGIN_DIR_OLD}'? [yes/no]: "
|
||||
read REMOVE
|
||||
REMOVE="$(echo "$REMOVE" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$REMOVE" != "yes" ]] && [[ "$REMOVE" != "no" ]] ; do
|
||||
echo -n "Wrong entry! - repeat [yes/no]: "
|
||||
read REMOVE
|
||||
done
|
||||
|
||||
if [[ "$REMOVE" = "yes" ]]; then
|
||||
rm -rf "$PLUGIN_DIR_OLD"
|
||||
if [[ $? -eq 0 ]]; then
|
||||
ok "Removed: ${PLUGIN_DIR_OLD}"
|
||||
else
|
||||
error "Failed to remove: ${PLUGIN_DIR_OLD}"
|
||||
fi
|
||||
else
|
||||
info "Keeping old plugin directory: ${PLUGIN_DIR_OLD}"
|
||||
fi
|
||||
else
|
||||
skip "No markasjunk2 plugin directory found – nothing to remove"
|
||||
fi
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Summary
|
||||
# -----------------------------------------------------------------------------
|
||||
echo ""
|
||||
echo "================================================================="
|
||||
echo " Summary"
|
||||
echo "================================================================="
|
||||
grep -n "markasjunk" "$RC_CONFIG" | while read line ; do
|
||||
info "config.inc.php line: $line"
|
||||
done
|
||||
[[ -f "$PLUGIN_CONFIG_NEW" ]] && ok "Plugin config: ${PLUGIN_CONFIG_NEW}" \
|
||||
|| warn "No plugin config – using built-in defaults"
|
||||
echo ""
|
||||
ok "Migration complete."
|
||||
echo ""
|
||||
+169
-1
@@ -296,6 +296,12 @@ DEFAULT_WEBSITE_BASEDIR="/var/www/${WEBSITE_NAME}"
|
||||
[[ -n "$WEBSITE_BASEDIR" ]] || WEBSITE_BASEDIR=$DEFAULT_WEBSITE_BASEDIR
|
||||
CUR_INSTALL_DIR="$(realpath "${WEBSITE_BASEDIR}/htdocs")"
|
||||
|
||||
# For Roundcube 1.7.x the symlink points to roundcubemail-x.y.z/public_html/
|
||||
# We need the parent roundcubemail directory, not public_html
|
||||
if [[ "$(basename "$CUR_INSTALL_DIR")" = "public_html" ]]; then
|
||||
CUR_INSTALL_DIR="$(dirname "$CUR_INSTALL_DIR")"
|
||||
fi
|
||||
|
||||
if [[ ! -d "$CUR_INSTALL_DIR" ]] ; then
|
||||
fatal "No current installation of roundcube found!"
|
||||
fi
|
||||
@@ -968,6 +974,70 @@ export COMPOSER_ALLOW_SUPERUSER=1
|
||||
export COMPOSER_ROOT_VERSION=${ROUNDCUBE_VERSION}
|
||||
|
||||
|
||||
echononl " Deactivate spellcheck_engine (pspell not available in PHP 8.4+).."
|
||||
if grep -q "spellcheck_engine.*pspell" "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php" 2>/dev/null ; then
|
||||
sed -i "s/\\\$config\['spellcheck_engine'\].*=.*'pspell'.*/\$config['spellcheck_engine'] = '';/" \
|
||||
"${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php" > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "$(cat $log_file)"
|
||||
fi
|
||||
else
|
||||
echo_skipped
|
||||
fi
|
||||
|
||||
|
||||
echononl " Replace deprecated markasjunk2 plugin with built-in markasjunk.."
|
||||
if grep -q "'markasjunk2'" "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php" 2>/dev/null ; then
|
||||
sed -i "s/'markasjunk2'/'markasjunk'/" \
|
||||
"${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/config/config.inc.php" > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "$(cat $log_file)"
|
||||
fi
|
||||
else
|
||||
echo_skipped
|
||||
fi
|
||||
|
||||
|
||||
echononl " Copy composer.json from source archive to installation directory.."
|
||||
cp "${script_dir}/roundcubemail-${ROUNDCUBE_VERSION}/composer.json" \
|
||||
"${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/composer.json" > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "$(cat $log_file)"
|
||||
|
||||
echononl "continue anyway [yes/no]: "
|
||||
read OK
|
||||
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
|
||||
echononl "Wrong entry! - repeat [yes/no]: "
|
||||
read OK
|
||||
done
|
||||
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
|
||||
fi
|
||||
|
||||
|
||||
echononl " Remove old composer.lock (force fresh dependency resolution).."
|
||||
if [[ -f "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/composer.lock" ]]; then
|
||||
rm "${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/composer.lock" > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "$(cat $log_file)"
|
||||
fi
|
||||
else
|
||||
echo_skipped
|
||||
fi
|
||||
|
||||
|
||||
echononl " Allow Plugins .."
|
||||
php composer.phar --no-interaction config allow-plugins.roundcube/plugin-installer true > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
@@ -1044,6 +1114,105 @@ else
|
||||
fi
|
||||
|
||||
|
||||
echononl " Regenerate Composer autoloader (remove stale files).."
|
||||
_autoload_dir="${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/vendor/composer"
|
||||
rm -f "${_autoload_dir}/autoload_real.php" \
|
||||
"${_autoload_dir}/ClassLoader.php" \
|
||||
"${_autoload_dir}/InstalledVersions.php" \
|
||||
"${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/vendor/autoload.php"
|
||||
php composer.phar --no-interaction dump-autoload > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "$(cat $log_file)"
|
||||
|
||||
echononl "continue anyway [yes/no]: "
|
||||
read OK
|
||||
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
|
||||
echononl "Wrong entry! - repeat [yes/no]: "
|
||||
read OK
|
||||
done
|
||||
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
|
||||
fi
|
||||
|
||||
|
||||
echononl " Run database schema migration (bin/updatedb.sh).."
|
||||
php ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/updatedb.sh \
|
||||
--package=roundcube \
|
||||
--dir=${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/SQL \
|
||||
> $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
# Check if failure is due to a partially applied migration ("already exists")
|
||||
if grep -q "already exists\|existiert bereits" $log_file ; then
|
||||
warn "DB migration had 'already exists' errors - attempting to skip failed migration and retry.."
|
||||
|
||||
# Extract the failed migration ID from the error output
|
||||
_failed_migration=$(grep -oE "\([0-9]{10}\)" $log_file | head -1 | tr -d '()')
|
||||
|
||||
if [[ -n "$_failed_migration" ]]; then
|
||||
info "Setting DB schema version to '${_failed_migration}' and retrying.."
|
||||
|
||||
if [[ "$DB_TYPE" = "pgsql" ]]; then
|
||||
su - postgres -c "${psql_command} -q -d ${DB_NAME} -c \
|
||||
\"UPDATE system SET value='${_failed_migration}' WHERE name='roundcube-version';\"" > $log_file 2>&1
|
||||
elif [[ "$DB_TYPE" = "mysql" ]]; then
|
||||
${mysql_command} ${MYSQL_CREDENTIALS} ${DB_NAME} -e \
|
||||
"UPDATE system SET value='${_failed_migration}' WHERE name='roundcube-version';" > $log_file 2>&1
|
||||
fi
|
||||
|
||||
# Retry migration
|
||||
php ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/updatedb.sh \
|
||||
--package=roundcube \
|
||||
--dir=${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/SQL \
|
||||
>> $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
echo_ok
|
||||
else
|
||||
echo_failed
|
||||
error "Retry also failed:\n$(cat $log_file)"
|
||||
|
||||
echononl "continue anyway [yes/no]: "
|
||||
read OK
|
||||
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
|
||||
echononl "Wrong entry! - repeat [yes/no]: "
|
||||
read OK
|
||||
done
|
||||
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
|
||||
fi
|
||||
else
|
||||
echo_failed
|
||||
error "Could not extract failed migration ID.\ncommand was:\n\t# php ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/updatedb.sh --package=roundcube --dir=${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/SQL\n\n$(cat $log_file)"
|
||||
|
||||
echononl "continue anyway [yes/no]: "
|
||||
read OK
|
||||
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
|
||||
echononl "Wrong entry! - repeat [yes/no]: "
|
||||
read OK
|
||||
done
|
||||
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
|
||||
fi
|
||||
else
|
||||
echo_failed
|
||||
error "command was:\n\t# php ${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/updatedb.sh --package=roundcube --dir=${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/SQL\n\n$(cat $log_file)"
|
||||
|
||||
echononl "continue anyway [yes/no]: "
|
||||
read OK
|
||||
OK="$(echo "$OK" | tr '[:upper:]' '[:lower:]')"
|
||||
while [[ "$OK" != "yes" ]] && [[ "$OK" != "no" ]] ; do
|
||||
echononl "Wrong entry! - repeat [yes/no]: "
|
||||
read OK
|
||||
done
|
||||
[[ $OK = "yes" ]] || fatal "Abbruch durch User"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
echononl " Index build-in addressbook"
|
||||
${WEBSITE_BASEDIR}/roundcubemail-${ROUNDCUBE_VERSION}/bin/indexcontacts.sh > $log_file 2>&1
|
||||
if [[ $? -eq 0 ]]; then
|
||||
@@ -1180,4 +1349,3 @@ fi
|
||||
|
||||
echo ""
|
||||
clean_up 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user