diff --git a/VERSION_CW b/VERSION_CW index 4eba2a62e..fdc669880 100644 --- a/VERSION_CW +++ b/VERSION_CW @@ -1 +1 @@ -3.13.0 +4.4.0 diff --git a/VERSION_CWCTL b/VERSION_CWCTL index 944880fa1..15a279981 100644 --- a/VERSION_CWCTL +++ b/VERSION_CWCTL @@ -1 +1 @@ -3.2.0 +3.3.0 diff --git a/deployment/chatwoot-web.target b/deployment/chatwoot-web.target new file mode 100644 index 000000000..759c7c443 --- /dev/null +++ b/deployment/chatwoot-web.target @@ -0,0 +1,6 @@ +[Unit] +Description=Chatwoot Web Server +Wants=chatwoot-web.1.service + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/deployment/chatwoot-worker.target b/deployment/chatwoot-worker.target new file mode 100644 index 000000000..265cb1156 --- /dev/null +++ b/deployment/chatwoot-worker.target @@ -0,0 +1,6 @@ +[Unit] +Description=Chatwoot Background Worker +Wants=chatwoot-worker.1.service + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/deployment/setup_20.04.sh b/deployment/setup_20.04.sh index 75320bbd3..d1091da3c 100644 --- a/deployment/setup_20.04.sh +++ b/deployment/setup_20.04.sh @@ -17,9 +17,9 @@ fi # Global variables # option --output/-o requires 1 argument -LONGOPTS=console,debug,help,install,Install:,logs:,restart,ssl,upgrade,webserver,version -OPTIONS=cdhiI:l:rsuwv -CWCTL_VERSION="3.2.0" +LONGOPTS=console,debug,help,install,Install:,logs:,restart,ssl,upgrade,Upgrade:,webserver,version,web-only,worker-only,convert: +OPTIONS=cdhiI:l:rsuU:wvWK +CWCTL_VERSION="3.3.0" pg_pass=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 15 ; echo '') CHATWOOT_HUB_URL="https://hub.2.chatwoot.com/events" @@ -42,7 +42,7 @@ fi # read getopt’s output this way to handle the quoting right: eval set -- "$PARSED" -c=n d=n h=n i=n I=n l=n r=n s=n u=n w=n v=n BRANCH=master SERVICE=web +c=n d=n h=n i=n I=n l=n r=n s=n u=n U=n w=n v=n W=n K=n C=n BRANCH=master SERVICE=web DEPLOYMENT_TYPE=full CONVERT_TO="" # Iterate options in order and nicely split until we see -- while true; do case "$1" in @@ -83,6 +83,12 @@ while true; do ;; -u|--upgrade) u=y + BRANCH="master" + break + ;; + -U|--Upgrade) + U=y + BRANCH="$2" break ;; -w|--webserver) @@ -93,6 +99,36 @@ while true; do v=y shift ;; + -W|--web-only) + W=y + DEPLOYMENT_TYPE=web + shift + ;; + -K|--worker-only) + K=y + DEPLOYMENT_TYPE=worker + shift + ;; + --convert) + C=y + CONVERT_TO="$2" + case "$CONVERT_TO" in + web) + DEPLOYMENT_TYPE=web + ;; + worker) + DEPLOYMENT_TYPE=worker + ;; + full) + DEPLOYMENT_TYPE=full + ;; + *) + echo "Invalid conversion type. Use: web, worker, or full" + exit 3 + ;; + esac + shift 2 + ;; --) shift break @@ -107,7 +143,7 @@ done # log if debug flag set if [ "$d" == "y" ]; then echo "console: $c, debug: $d, help: $h, install: $i, Install: $I, BRANCH: $BRANCH, \ - logs: $l, SERVICE: $SERVICE, ssl: $s, upgrade: $u, webserver: $w" + logs: $l, SERVICE: $SERVICE, ssl: $s, upgrade: $u, Upgrade: $U, webserver: $w, web-only: $W, worker-only: $K, convert: $C, convert-to: $CONVERT_TO, deployment-type: $DEPLOYMENT_TYPE" fi # exit if script is not run as root @@ -379,23 +415,84 @@ EOF ############################################################################## # Setup Chatwoot systemd services and cwctl CLI # Globals: -# None +# DEPLOYMENT_TYPE # Arguments: # None # Outputs: # None ############################################################################## function configure_systemd_services() { - cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + # Check if this is a conversion from existing deployment + local existing_full_deployment=false + if [ -f "/etc/systemd/system/chatwoot.target" ]; then + existing_full_deployment=true + fi + + if [ "$DEPLOYMENT_TYPE" == "web" ]; then + echo "Setting up web-only deployment" + + # Stop and disable existing services if converting + if [ "$existing_full_deployment" = true ]; then + echo "Converting from full deployment to web-only" + systemctl stop chatwoot.target || true + systemctl disable chatwoot.target || true + systemctl stop chatwoot-worker.1.service || true + systemctl disable chatwoot-worker.1.service || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.target /etc/systemd/system/chatwoot-web.target + + systemctl daemon-reload + systemctl enable chatwoot-web.target + systemctl start chatwoot-web.target + + elif [ "$DEPLOYMENT_TYPE" == "worker" ]; then + echo "Setting up worker-only deployment" + + # Stop and disable existing services if converting + if [ "$existing_full_deployment" = true ]; then + echo "Converting from full deployment to worker-only" + systemctl stop chatwoot.target || true + systemctl disable chatwoot.target || true + systemctl stop chatwoot-web.1.service || true + systemctl disable chatwoot-web.1.service || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.target /etc/systemd/system/chatwoot-worker.target + + systemctl daemon-reload + systemctl enable chatwoot-worker.target + systemctl start chatwoot-worker.target + + else + echo "Setting up full deployment (web + worker)" + + # Stop existing specialized deployments if converting back to full + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + echo "Converting from web-only to full deployment" + systemctl stop chatwoot-web.target || true + systemctl disable chatwoot-web.target || true + fi + if [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + echo "Converting from worker-only to full deployment" + systemctl stop chatwoot-worker.target || true + systemctl disable chatwoot-worker.target || true + fi + + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + + systemctl daemon-reload + systemctl enable chatwoot.target + systemctl start chatwoot.target + fi cp /home/chatwoot/chatwoot/deployment/chatwoot /etc/sudoers.d/chatwoot cp /home/chatwoot/chatwoot/deployment/setup_20.04.sh /usr/local/bin/cwctl chmod +x /usr/local/bin/cwctl - - systemctl enable chatwoot.target - systemctl start chatwoot.target } ############################################################################## @@ -427,7 +524,15 @@ function setup_ssl() { cd chatwoot sed -i "s/http:\/\/0.0.0.0:3000/https:\/\/$domain_name/g" .env EOF - systemctl restart chatwoot.target + + # Restart the appropriate chatwoot target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + else + systemctl restart chatwoot.target + fi } ############################################################################## @@ -624,17 +729,27 @@ Usage: cwctl [OPTION]... Install and manage your Chatwoot installation. Example: cwctl -i master +Example: cwctl -i --web-only (for web server ASG) +Example: cwctl -i --worker-only (for worker ASG) +Example: cwctl --convert web (convert existing to web-only) +Example: cwctl --convert worker (convert existing to worker-only) +Example: cwctl --convert full (convert back to full deployment) +Example: cwctl --upgrade (upgrade to latest master) +Example: cwctl -U develop (upgrade to develop branch) Example: cwctl -l web Example: cwctl --logs worker -Example: cwctl --upgrade Example: cwctl -c Installation/Upgrade: -i, --install Install the latest stable version of Chatwoot - -I Install Chatwoot from a git branch + -I BRANCH Install Chatwoot from a git branch -u, --upgrade Upgrade Chatwoot to the latest stable version + -U BRANCH Upgrade Chatwoot from a git branch (EXPERIMENTAL) -s, --ssl Fetch and install SSL certificates using LetsEncrypt -w, --webserver Install and configure Nginx webserver with SSL + -W, --web-only Install only the web server (for ASG deployment) + -K, --worker-only Install only the background worker (for ASG deployment) + --convert TYPE Convert existing deployment (TYPE: web, worker, full) Management: -c, --console Open ruby console @@ -831,7 +946,31 @@ EOF function upgrade() { cwctl_upgrade_check get_cw_version - echo "Upgrading Chatwoot to v$CW_VERSION" + echo "Upgrading Chatwoot to v$CW_VERSION (branch: $BRANCH)" + + # Warning for non-master branch upgrades + if [ "$BRANCH" != "master" ]; then + cat << EOF + +⚠️ WARNING: Branch-specific upgrades are EXPERIMENTAL +⚠️ Switching between different versions/branches may cause: + - Database migration conflicts + - Asset compilation errors + - Configuration incompatibilities + - Data corruption or loss + +⚠️ This is NOT recommended for production environments. +⚠️ Always backup your database before proceeding. + +EOF + read -p "Do you understand the risks and want to continue? [y/N]: " user_input + user_input=${user_input:-N} + if [[ ! "$user_input" =~ ^([yY][eE][sS]|[yY])$ ]]; then + echo "Upgrade cancelled." + exit 1 + fi + fi + sleep 3 # Check if CW_VERSION is 4.0 or above @@ -857,8 +996,9 @@ function upgrade() { # Navigate to the Chatwoot directory cd chatwoot - # Pull the latest version of the master branch - git checkout master && git pull + # Pull the latest version of the specified branch + git fetch + git checkout "$BRANCH" && git pull # Ensure the ruby version is upto date # Parse the latest ruby version @@ -878,18 +1018,35 @@ function upgrade() { EOF - # Copy the updated targets - cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service - cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + # Copy the updated services and targets based on existing deployment + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + echo "Updating web-only deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.target /etc/systemd/system/chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + echo "Updating worker-only deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.target /etc/systemd/system/chatwoot-worker.target + else + echo "Updating full deployment" + cp /home/chatwoot/chatwoot/deployment/chatwoot-web.1.service /etc/systemd/system/chatwoot-web.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot-worker.1.service /etc/systemd/system/chatwoot-worker.1.service + cp /home/chatwoot/chatwoot/deployment/chatwoot.target /etc/systemd/system/chatwoot.target + fi cp /home/chatwoot/chatwoot/deployment/chatwoot /etc/sudoers.d/chatwoot # TODO:(@vn) handle cwctl updates systemctl daemon-reload - # Restart the chatwoot server - systemctl restart chatwoot.target + # Restart the appropriate chatwoot target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + else + systemctl restart chatwoot.target + fi } @@ -903,8 +1060,40 @@ EOF # None ############################################################################## function restart() { - systemctl restart chatwoot.target - systemctl status chatwoot.target + if [ -f "/etc/systemd/system/chatwoot-web.target" ]; then + systemctl restart chatwoot-web.target + systemctl status chatwoot-web.target + elif [ -f "/etc/systemd/system/chatwoot-worker.target" ]; then + systemctl restart chatwoot-worker.target + systemctl status chatwoot-worker.target + else + systemctl restart chatwoot.target + systemctl status chatwoot.target + fi +} + +############################################################################## +# Convert existing Chatwoot deployment to different type (--convert) +# Globals: +# DEPLOYMENT_TYPE +# Arguments: +# None +# Outputs: +# None +############################################################################## +function convert_deployment() { + echo "Converting Chatwoot deployment to: $DEPLOYMENT_TYPE" + + # Check if Chatwoot is installed + if [ ! -d "/home/chatwoot/chatwoot" ]; then + echo "Chatwoot installation not found. Use --install first." + exit 1 + fi + + # Run the systemd service configuration which handles conversion logic + configure_systemd_services + + echo "Deployment converted successfully to: $DEPLOYMENT_TYPE" } ############################################################################## @@ -1107,7 +1296,7 @@ function main() { ssl fi - if [ "$u" == "y" ]; then + if [ "$u" == "y" ] || [ "$U" == "y" ]; then report_event "cwctl" "upgrade" > /dev/null 2>&1 upgrade fi @@ -1122,6 +1311,11 @@ function main() { version fi + if [ "$C" == "y" ]; then + report_event "cwctl" "convert" > /dev/null 2>&1 + convert_deployment + fi + } main "$@"