| Server IP : 104.129.129.72 / Your IP : 216.73.216.229 Web Server : LiteSpeed System : Linux 123answers 5.15.0-143-generic #153-Ubuntu SMP Fri Jun 13 19:10:45 UTC 2025 x86_64 User : answe8064 ( 1002) PHP Version : 8.2.28 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /opt/installer/services/ |
Upload File : |
#!/bin/bash
: '
NOTE:
This image is special since it creates multiple nodes using CWM api.
In case of an error, these nodes must be terminated, thus using waitOrStop function is problematic.
Instead a flag will be used, termination will be desided upon the flag.
'
if [ -f "include/startup.sh" ]; then
. include/startup.sh
elif [ -f "../include/startup.sh" ]; then
. ../include/startup.sh
fi
rootDir=$(rootDir)
termination_flag=0
nodes_names=()
####### Deploying CWM Nodes #######
## NODE 1
clientId=${CWM_APICLIENTID}
secret=${CWM_APISECRET}
datacenter=${CWM_ZONE}
#last_oct=$((RANDOM % 231 + 10)) # Random number between 10 - 240 to define as last octat for nodes
# Define last octet for first new Node (the rest will be calculated by additional 1 each)
# Extract the last octet from the input variable
origin_last_oct=$(echo "$CWM_IP1" | awk -F '.' '{print $4}')
# Calculate the new value for the last octet
if ((origin_last_oct < 10)); then
last_oct=$((RANDOM % 230 + 11))
else
#last_oct=$((RANDOM % (origin_last_oct - 3) + 1))
last_oct=3
fi
echo "IP of ClusterControl: ${CWM_IP1}" | log
for i in {1..3}
do
node_num=${i}
name="${CWM_NAME}_NODE_${node_num}"
password=${ADMINPASSWORD}
cpu="2B"
ram="2048"
billing="monthly"
managed="0"
backup="0"
power="1"
traffic="3"
disk_size_0="10"
# note: parameters requires url encoding - ubuntu 20
disk_src_0="${CWM_ZONE}:6000C29f313b496da71f669782d04b75"
network_name_0="wan"
network_name_1=$CWM_VLAN1
# Extract the first three octets of the IP address
FIRST_THREE_OCTETS=$(echo $CWM_IP1 | cut -d '.' -f 1-3)
#echo "first free octats: ${FIRST_THREE_OCTETS}" | log
# Set the last octet to a new value
NEW_LAST_OCTET=$((last_oct+i))
# Combine the first three octets and the new last octet to form the new IP address
NEW_IP_ADDRESS="$FIRST_THREE_OCTETS.$NEW_LAST_OCTET"
#echo "New ip address: ${NEW_IP_ADDRESS}" | log
# Print the new IP address
echo "New IP address for node ${i} is: ${NEW_IP_ADDRESS}" | log
eval node_${i}_ip=$NEW_IP_ADDRESS
#eval "echo \"node ${i} new ip address \${node_${i}_ip}\"" | log
# Define the cwm api request
params="datacenter=${datacenter}"
params+="&name=${name}"
params+="&password=${password}"
params+="&cpu=${cpu}"
params+="&ram=${ram}"
params+="&billing=${billing}"
params+="&managed=${managed}"
params+="&backup=${backup}"
params+="&power=${power}"
params+="&traffic=${traffic}"
params+="&disk_size_0=${disk_size_0}"
params+="&disk_src_0=${disk_src_0}"
params+="&network_name_0=${network_name_0}"
params+="&network_name_1=${network_name_1}"
params+="&network_ip_1=${NEW_IP_ADDRESS}"
echo "CWM API: Create new node with IP: ${NEW_IP_ADDRESS} from CWM" | log
response=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" -X POST -d "${params}" "https://null.cloudwm.com/service/server")
echo "CWM API RESPONSE:${response}" | log
# Remove spaces
error_code=$(echo "$response" | grep -oP '(?<="code":)\d+')
echo "API CREATE - error code: $error_code" | log
if [ ! -z "$error_code" ]; then
echo "terminatin_flag switched to 1: error_code of node exists" | log
echo "error_code for node ${i} creation was ${error_code}" | log
termination_flag=1
fi
#if [[ ${error_code} -eq 102 ]]
#then
# false - returns non-zero status
#false
#waitOrStop 0 "Failed Node ${i} deploy: generated name already taken"
#fi
#if [[ ${error_code} -eq 117 ]]
#then
# false - returns non-zero status
#false
#waitOrStop 0 "Failed Node ${i} deploy: choosen vlan doesnt exist"
#fi
# If api request was successful grab the command ID:
# Sleep to wait for command appear in CWM
sleep 10
echo "Using CWM API to track ID of creation command for node ${i}"
command_id="${response//[!0-9]/}"
response_command=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" "https://null.cloudwm.com/service/queue/${command_id}")
echo "CWM API COMMAND INFO RESPONSE:${response_command}" | log
# Extract name of Node that was created in case termination will be required duting the script
# Extract the value of the "description" field using grep and cut
response_description=$(echo "$response_command" | grep -oP '(?<="description": ")[^"]*')
echo "Description from api respond to command info: ${response_description}" | log
# Extract the substring before " - Create Server" using bash string manipulation
eval node_${i}_name=${response_description%% - Create Server}
temp_node_name=${response_description%% - Create Server}
echo "Extracting Node ${i} name for termination, if required" | log
echo "Node ${i} name: ${temp_node_name}" | log
#eval "echo \"node ${i} new name \${node_${i}_name}\"" | log
nodes_names+=( "$temp_node_name" )
done
#########################################################
if [ "$termination_flag" -eq 0 ]; then
echo "Get ansible Role" | log
ansible-galaxy install severalnines.clustercontrol | log
#waitOrStop 0 "Failed Get ansible Role"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed: termination_flag=1 Get ansible Role" | log
fi
echo "install MariaDB" | log
installPackage mariadb-server | log
#waitOrStop 0 "Failed install MariaDB - server"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed install MariaDB - server termination_flag=1" | log
fi
installPackage mariadb-client | log
#waitOrStop 0 "Failed install MariaDB - client"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed install MariaDB - client termination_flag=1" | log
fi
apt update
echo "Create ansible playbook" | log
cd /root
touch cc.playbook
cat <<EOF > cc.playbook
- hosts: localhost
roles:
- { role: severalnines.clustercontrol }
EOF
echo "runing playbook" | log
ansible-playbook cc.playbook | log
#### SSL ####
echo "Installing certbot for apache" | log
installPackage python3-certbot-apache
#waitOrStop 0 "Failed apt install: python-certbot-apache"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed apt install: python-certbot-apache termination_flag=1" | log
fi
## applying ssl for cc web app ##
systemctl stop apache2.service
execSpecial 3 '(fail|error)' certbot certonly -n --standalone --preferred-challenges http --agree-tos --email ${ADMINEMAIL} -d ${CWM_DOMAIN} ${CWM_DEBUG:+"--test-cert"}
if [[ $? == 1 ]]
then
export certbot_failed=1
echo "Generating self-signed certificate" | log
#waitOrStop 0 "Failed certbot certificate generation"
mkdir /etc/letsencrypt/live
mkdir /etc/letsencrypt/live/${CWM_DOMAIN}
openssl req -x509 -sha256 -newkey rsa:2048 -keyout /etc/letsencrypt/live/${CWM_DOMAIN}/privkey.pem -out /etc/letsencrypt/live/${CWM_DOMAIN}/fullchain.pem -days 1024 -nodes -subj '/CN=localhost'
#waitOrStop 0 "Certificate creation failed"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Certificate creation failed termination_flag=1" | log
fi
# Sending log to log server - 45-93-93-142.cloud-xip.com
curl -v -X POST -D -H "Content-Type: application/x-www-form-urlencoded" -d "vm_name='$CWM_NAME'&image_name='$CWM_OS'&vm_owner='$ADMINEMAIL'" http://45-93-93-142.cloud-xip.com
else
export certbot_failed=0
fi
export CWM_DISPLAYED_ADDRESS="${CWM_DOMAIN}"
systemctl start apache2.service
#waitOrStop 0 "Failed to start Apache service"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed to start Apache service termination_flag=1" | log
fi
tag global-domain-set.success
echo "Reconfigure SSL in Vhost" | log
sed -i "s|^[ \t]*SSLCertificateFile.*|SSLCertificateFile /etc/letsencrypt/live/$CWM_DOMAIN/fullchain.pem|g" /etc/apache2/sites-available/s9s-ssl.conf
sed -i "s|^[ \t]*SSLCertificateKeyFile.*|SSLCertificateKeyFile /etc/letsencrypt/live/$CWM_DOMAIN/privkey.pem|g" /etc/apache2/sites-available/s9s-ssl.conf
#waitOrStop 0 "Failed Reconfigure SSL in Vhost"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed Reconfigure SSL in Vhost termination_flag=1" | log
fi
systemctl restart apache2.service
#waitOrStop 0 "Failed restart apache2.service"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed restart apache2.service termination_flag=1" | log
fi
#### SSL END ####
## Remove Ansible ##
apt-get remove -y ansible
## Create new rpc-key and modify relevant files ##
random_rpc=$(date +%s | sha256sum | base64 | head -c 32 ; echo)
echo "rpc_key=${random_rpc}" >> /etc/cmon.cnf
sed -i "s|define('RPC_TOKEN'|//define('RPC_TOKEN'|g" /var/www/html/clustercontrol/bootstrap.php
echo "define('RPC_TOKEN', '${random_rpc}');" >> /var/www/html/clustercontrol/bootstrap.php
###################################################
## Deploy Galera Cluster ##
# wait until cmon is up
echo "waiting for cmon" | log
while ! nc -z localhost 9501; do
sleep 1
done
## Check that Nodes are responding ##
# IP addresses to ping
ip1=$node_1_ip
ip2=$node_2_ip
ip3=$node_3_ip
# Loop until all IPs have SSH service
echo "testing ssh for ${ip1}, ${ip2}, ${ip3}, timeout is set for 100*5 seconds" | log
ip_while_counter=0
while true && ((ip_while_counter<100)); do
if nc -zv "$ip1" 22 >/dev/null && nc -zv "$ip2" 22 >/dev/null && nc -zv "$ip3" 22 >/dev/null; then
break
else
echo "not all servers are listening on 22 yet" | log
sleep 5
ip_while_counter=$((ip_while_counter+1))
echo "counter is ${ip_while_counter}"
fi
done
echo "All IPs have SSH service." | log
echo "Testing for time out of node deployment" | log
if [[ ip_while_counter -eq 100 ]]
then
false
#waitOrStop 0 "Failed: time out while waiting node deployment"
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed: time out while waiting node deployment termination_flag=1" | log
fi
fi
echo "adding public key to nodes" | log
apt-get install sshpass
ips=($node_1_ip $node_2_ip $node_3_ip)
echo "Coping ssh-keys nodes" | log
for ip in "${ips[@]}"; do
echo "Copying SSH key to $ip"
sshpass -p ${ADMINPASSWORD} ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa root@$ip 'cat >> /root/.ssh/authorized_keys' < /root/.ssh/id_rsa.pub
done
#echo "Fix issues with admin user:" | log
#echo "backing up s9s.conf to backup" | log
#mv /etc/s9s.conf /etc/s9s.conf.bak
#echo "Creating dba user to enable admin" | log
#s9s user --create --generate-key --controller="https://localhost:9501" --group=admins dba
#sleep 1
#s9s user --cmon-user=dba --enable admin
#sleep 1
#echo "using reset ccrpc script" | log
#echo "yes" | /var/www/clustercontrol/app/tools/reset-ccrpc.sh
#sleep 10
## Create cmon user named dba
s9s user --create \
--generate-key \
--controller="https://localhost:9501" \
--group=admins dba
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed: s9s user create" | log
fi
echo "Deploying: Run Galera (percona) with 3 servers" | log
s9s cluster --create \
--cluster-type=galera \
--nodes="${node_1_ip};${node_2_ip};${node_3_ip}" \
--vendor=percona \
--provider-version=5.7 \
--db-admin-passwd='${ADMINPASSWORD}' \
--os-user=root \
--os-key-file=/root/.ssh/id_rsa \
--cluster-name='Percona XtraDB Cluster 5.7' \
--wait
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed: s9s deploy galera termination_flag=1" | log
fi
s9s cluster --add-node \
--cluster-id=1 \
--nodes="haproxy://${CWM_SERVERIP}" \
--wait
if [ $? -ne 0 ]; then
termination_flag=1
echo "Failed: s9s deploy haproxy termination_flag=1" | log
fi
echo "Adding descriptions" | log
descriptionAppend "Three Nodes should have been created, please make sure you see the nodes in your panel "
descriptionAppend "Run before registration:/var/www/html/clustercontrol/app/tools/reset-ccrpc.sh "
descriptionAppend "clustercontrol web page: ${CWM_DOMAIN}/clustercontrol"
descriptionAppend "cmon config files location: /etc/cmon.cnf"
descriptionAppend "mariaDB user password: ${ADMINPASSWORD}"
descriptionAppend "Galera Cluster users info can be accessed from CC web page after registration"
descriptionAppend "clustercontrol webpage config: /var/www/clustercontrol/bootstrap.php"
descriptionAppend "rpc-key: ${random_rpc}"
descriptionAppend "cmon user(dba) auth: /root/.s9s"
descriptionAppend "Connection String: ${CWM_SERVERIP}:3307 - HAproxy will loadbalance 3306 requests through this port"
descriptionAppend "You should create new mysql user from CC webpage to authenticate at ${CWM_SERVERIP}:3307"
descriptionAppend " "
fi
if [ "$termination_flag" -eq 1 ]; then
installPackage jq
for i in "${nodes_names[@]}"
do
echo "element in array is: $i" | log
done
# Terminate created nodes:
for i in {1..3}
do
# j is used for the nodes_names array access
j=$((i-1))
echo "j is: ${j}" | log
#eval "node_name=\${${nodes_names[$j]}}"
node_name="${nodes_names[j]}"
echo "By j indexing, node name now is: ${node_name}" | log
if [ ! -z "$node_name" ]; then
# SLEEP UNTIL ALL NODES ARE CREATED (TO BE TERMINATED)
echo "Termination: Sleeping until node ${i} responding" | log
current_ip_var="node_${i}_ip"
current_ip="${!current_ip_var}"
ip_while_counter=0
while true && ((ip_while_counter<100)); do
if nc -zv "$current_ip" 22 >/dev/null; then
break
else
echo "Termination sleep: ${current_ip} is not listening on 22 yet" | log
sleep 5
ip_while_counter=$((ip_while_counter+1))
echo "counter is ${ip_while_counter}"
fi
done
echo "Termination: All IPs have SSH service." | log
echo "currently trying to terminate node: ${node_name}" | log
echo "Fetching server create options with api call to CWM" | log
curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" "https://null.cloudwm.com/service/servers" > listServers.json
LIST=$(cat listServers.json | jq -r ".[] | select(.name|test(\"$node_name\")) | .id")
echo "Before for loog of termination Server IDs: ${LIST[@]}" | log
## Building list of termination ##
#echo "Found these images:" | log
#imageArray=()
#for imageId in $LIST; do
# imageDescription=`cat listServers.json | jq -r '.[] | select(.id|test("'$imageId'")) | .name'`
# echo "Image ID: $imageId: $imageDescription" | log
# imageArray+=("Image ID: $imageId : $imageDescription")
#done
## Termination ##
for serverId in $LIST; do
echo "Terminating server name:${node_name}, id:${serverId}" | log
confirm="1"
force="1"
echo "terminatin node: ${node_name}" | log
response_termination=$(curl -H "AuthClientId: ${clientId}" -H "AuthSecret: ${secret}" -X DELETE -d "confirm=${confirm}" -d "force=${force}" "https://console.kamatera.com/service/server/${serverId}/terminate")
echo "CWM TERMINATION for ${node_name} response is: ${response_termination}" | log
done
fi
done
# exiting
false
waitOrStop 0 "Somthing went wrong in Cluster Deploy Script, check the logs"
fi
tag ssl-ready.success
tagScript success
tag apache2.success
tag certbot-apache2.success
tagScript success
exit 0