#!/usr/bin/env bash
#########################################
#Copyright (c) 2023 ABLECLOUD Co. Ltd.
#
#ccvm 초기화(bootstrap)하는 스크립트
#
#최초작성자 : 배태주 책임
#최초작성일 : 2023-07-12
#########################################
# set -x
LOGFILE="/var/log/mold_install.log"

re1="[0-9]"
re2="[a-z]"
re3="[A-Z]"
re4="[~\!@#$%^&*()]"
keyboard="qwertyuiop asdfghjkl zxcvbnm 1234567890 poiuytrewq lkjhgfdsa mnbvcxz 0987654321"
DATABASE_PASSWD=""


echo " ### Please Enter a New DB Password ### "
while :
do
    echo -n "New Password : "
    read -s db_pass
    echo " "

    echo -n "New Password Check : "
    read -s db_pass_check
    echo " "

    #동일한 문자·숫자의 연속적인 반복입력 금지
    echo $db_pass  | grep "\([0-9a-zA-Z~\!@#$%^&*()]\)\1\1"  > /dev/null
    re5=$?

    #키보드상의 연속된 문자 또는 숫자의 순차적 입력금지
    re6=0
    t_pass=$(echo "$db_pass" | tr '[:upper:]' '[:lower:]')
    for ((i = 0 ; i <= ${#t_pass}-3 ; i++))
    do
        split_pass_str=$(echo ${t_pass:$i:4})
            for keyboard_str in $keyboard
            do
            if [[ "$keyboard_str" =~ $split_pass_str ]]; then
                re6=1
                break 2
            else
                re6=0
            fi
        done
    done

    # 계정과 동일 문자 금지
    user_info=$(whoami | tr '[:upper:]' '[:lower:]')
    echo $t_pass | grep $user_info
    re7=$?

    if [[ "$db_pass" == "$db_pass_check" ]] && [[ "$db_pass" =~ $re1 ]] && [[ "$db_pass" =~ $re2 ]] && [[ "$db_pass" =~ $re3 ]] && [[ "$db_pass" =~ $re4 ]] && [[ $re5 -eq 1 ]] && [[ $re6 -eq 0 ]] && [[ $re7 -eq 1 ]] && [[ ${#db_pass} -ge 9 ]] && [[ ${#db_pass} -le 15 ]]; then
        DATABASE_PASSWD=$db_pass
        break
    else
        echo "[Invalid Password] Please check your new DB password again."
    fi
done
echo "DB password setting completed!"
# db 비밀번호 입력 완료

dnf -y --nogpgcheck install /opt/ABLESTACK-V4.0-4.0.15/rpms/* 2>&1 | tee -a $LOGFILE
dnf -y --nogpgcheck install /opt/ABLESTACK-V4.0-4.0.15/mold_rpms/* 2>&1 | tee -a $LOGFILE

tar -xzvf /opt/ABLESTACK-V4.0-4.0.15/openssl/openssl-3.3.0.tar.gz -C /opt/ABLESTACK-V4.0-4.0.15/openssl/ 2>&1 | tee -a $LOGFILE
cd /opt/ABLESTACK-V4.0-4.0.15/openssl/openssl-3.3.0
./config --prefix=/usr --openssldir=/etc/ssl --libdir=lib no-shared zlib-dynamic 2>&1 | tee -a $LOGFILE
make 2>&1 | tee -a $LOGFILE
make install 2>&1 | tee -a $LOGFILE

# server.properties https 적용
sed -i 's/http.enable=true/http.enable=false/g' /etc/cloudstack/management/server.properties
sed -i 's/https.enable=false/https.enable=true/g' /etc/cloudstack/management/server.properties
sed -i "s/vmops.com/$DATABASE_PASSWD/g" /etc/cloudstack/management/server.properties

keytool -genkey -alias ablecloud -keyalg RSA -keypass $DATABASE_PASSWD -storepass $DATABASE_PASSWD -validity 365 -keystore /etc/cloudstack/management/cloud.jks <<EOF
ABLECLOUD
ABLECLOUD
ABLECLOUD
Seoul
Republic of Korea
82
yes
EOF

chmod 777 /etc/cloudstack/management/cloud.jks

sed -i "s/\[openssl_init\]/\[openssl_init\]\\nrandom = random/" /etc/ssl/openssl.cnf
echo "" >> /etc/ssl/openssl.cnf && echo "[random]">> /etc/ssl/openssl.cnf && echo "random = HMAC-DRBG" >> /etc/ssl/openssl.cnf && echo "digest = SHA-256" >> /etc/ssl/openssl.cnf

systemctl enable --now mysqld

# 데이터베이스 DB 비밀번호를 암호화 하기 위해 사용하는 암호키(DEK)를 생성
openssl rand -base64 32 > dek1_key
# dek1_key 를 16진수로 변환하여 저장
zero=0
dek1_key=$(echo `echo $(od -xL dek1_key)` | tr -d ' ' | cut -c -64)
if [[ ${#dek1_key} < 64 ]]; then
        length=$((64 - ${#dek1_key}))
        count=0
        while [ $count -le $length ];
        do
                hex_str=$dek1_key$zero
                count=$((count+1))
                dek1_key=$hex_str
        done
fi
DATABASE_PASSWD_DEK_RAND=$dek1_key

# 데이터베이스 데이터를 암호화 하기 위해 사용하는 암호키(DEK)를 생성
openssl rand -base64 32 > dek2_key
# dek2_key 를 16진수로 변환하여 저장
dek2_key=$(echo `echo $(od -xL dek2_key)` | tr -d ' ' | cut -c -64)
if [[ ${#dek2_key} < 64 ]]; then
        length=$((64 - ${#dek2_key}))
        count=0
        while [ $count -le $length ];
        do
                hex_str=$dek2_key$zero
                count=$((count+1))
                dek2_key=$hex_str
        done
fi
DATABASE_DATA_DEK_RAND=$dek2_key

################# firewall setting
firewall-cmd --permanent --zone=public --add-port=8080/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=8443/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=3306/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=4444/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=4567/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=4568/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=4569/tcp 2>&1 | tee -a $LOGFILE

firewall-cmd --permanent --zone=public --add-port=20048/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=20048/udp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=21064/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=2049/tcp 2>&1 | tee -a $LOGFILE

firewall-cmd --permanent --zone=public --add-port=875/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=32803/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=32769/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=892/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=600/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=662/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-port=8250/tcp 2>&1 | tee -a $LOGFILE
firewall-cmd --permanent --zone=public --add-service=mysql 2>&1 | tee -a $LOGFILE

firewall-cmd --reload
firewall-cmd --list-all 2>&1 | tee -a $LOGFILE

#nfs 구성
mkdir /nfs
echo '/nfs *(rw,no_root_squash,async)' >> /etc/exports
systemctl enable --now nfs-server.service

mkdir /nfs/primary
mkdir /nfs/secondary

################# Setting Database
#mysqladmin -uroot password $DATABASE_PASSWD
#mysql 초기비밀번호 세팅
count=0
while [ $count -lt 40 ]
do
    initial_password=$(cat /var/log/mysqld.log | grep "A temporary password is"| awk '{print $13}')
    if [ $initial_password != '' ]; then
        expect -c "
        set timeout 20
        spawn mysql -u root -p
        expect \"Enter password:\"
        send \"$initial_password\n\"
        expect \"mysql>\"
        send \"ALTER USER 'root'@'localhost' identified by '$DATABASE_PASSWD';\n\"
        send \"exit\n\"
        expect \"$\"
        exit 0
        "
        break
    fi
	sleep 15;
	count=$((count+1))
done
setenforce 0
systemctl enable --now cloudstack-usage

#sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
#cloudstack-setup-databases cloud:$DATABASE_PASSWD --deploy-as=root:$DATABASE_PASSWD 2>&1 | tee -a $LOGFILE
cloudstack-setup-databases cloud:$DATABASE_PASSWD --deploy-as=root:$DATABASE_PASSWD -m $DATABASE_PASSWD_DEK_RAND -k $DATABASE_DATA_DEK_RAND 2>&1 | tee -a $LOGFILE

# Cloudstack Global Setting
global_settings=("user.password.encoders.order=SHA256SALT,MD5,LDAP,PLAINTEXT" \
"user.password.encoders.exclude=" "usage.execution.timezone=Asia/Seoul" \
"network.loadbalancer.haproxy.stats.visibility=all" \
"storage.overprovisioning.factor=1" "enable.dynamic.scale.vm=true" \
"kvm.ha.activity.check.interval=60" "kvm.ha.activity.check.max.attempts=10" \
"kvm.ha.activity.check.timeout=60" "kvm.snapshot.enabled=true" )
for i in "${global_settings[@]}"
do
  key=$(echo $i | cut -d "=" -f 1)
  value=$(echo $i | cut -d "=" -f 2)
  mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; UPDATE configuration SET value='$value' where name='$key';"  2>&1 | tee -a $LOGFILE
done

cloudstack-setup-management 2>&1 | tee -a $LOGFILE

#systemvm template 등록
/usr/share/cloudstack-common/scripts/storage/secondary/cloud-install-sys-tmplt \
-m /nfs/secondary \
-f /opt/ABLESTACK-V4.0-4.0.15/systemvmtemplate-* \
-h kvm -F  | tee -a $LOGFILE

################# Integrity Verification
# management 서비스 체크
# 15초 간격으로 서비스가 정상적으로 올라왔는지 체크하며, 10분 이후에 실패/성공에 상관없이 Integrity Verification 실행
count=0
while [ $count -lt 40 ]
do
	cnt=$(mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; select count(1) as cnt from version")
	num=$(echo $cnt | cut -d ' ' -f2)
	if [  $num -ge 43 ]; then
		event=$(mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; select count(*) cnt from information_schema.COLUMNS where table_name='event' and column_name='resource_id'")
        num2=$(echo $event | cut -d ' ' -f2)
        if [ $num2 -ge 1 ]; then
            break
        fi
	fi
	sleep 15;
	count=$((count+1))
done

HOST_IP=$(hostname -i)

# 암호키 생성 성공 여부 감사로그 생성
if [[ ! -n "$DATABASE_PASSWD_DEK_RAND" ]] || [[ -z "$DATABASE_PASSWD_DEK_RAND" ]]; then
        UUID=$(cat /proc/sys/kernel/random/uuid)
        mysql -uroot -t cloud -p$DATABASE_PASSWD "use cloud; INSERT INTO event (uuid, type, state, description, user_id, account_id, domain_id, resource_id, created, level, start_id, archived, display, client_ip) VALUES ('$UUID', 'ENCRYPTION.CHECK', 'Completed', 'Encryption key creation failed : Create DBSecretKey, generate pseudo-random bytes.', '2', '2', '1', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'ERORR', '0', '0', '1', '$HOST_IP');"
        exit 1
fi

if [[ ! -n "$DATABASE_DATA_DEK_RAND" ]] || [[ -z "$DATABASE_DATA_DEK_RAND" ]]; then
        UUID=$(cat /proc/sys/kernel/random/uuid)
        mysql -uroot -t cloud -p$DATABASE_PASSWD "use cloud; INSERT INTO event (uuid, type, state, description, user_id, account_id, domain_id, resource_id, created, level, start_id, archived, display, client_ip) VALUES ('$UUID', 'ENCRYPTION.CHECK', 'Completed', 'Encryption key creation failed : Create DBSecretKey, generate pseudo-random bytes.', '2', '2', '1', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'ERORR', '0', '0', '1', '$HOST_IP');"
        exit 1
fi

# 생성된 암호키 난수 값을 0과 1로 덮어쓰기
for var in {1..5}
do
  DATABASE_PASSWD_DEK_RAND=01010101
  DATABASE_DATA_DEK_RAND=01010101
  dek1_key=01010101
  dek2_key=01010101
done

# 실제 파일 삭제
rm -rf dek1_key dek2_key

# mold-monitoring 서비스 
echo "[Unit]
Description=Mold Monitoring Service
After=syslog.target network.target

[Service]
UMask=0022
Type=simple
User=cloud
ExecStart=/usr/share/cloudstack-common/scripts/security/moldmonitoring.sh

[Install]
WantedBy=multi-user.target" > /usr/lib/systemd/system/mold-monitoring.service

systemctl daemon-reload 2>&1 | tee -a $LOGFILE
systemctl enable --now mold-monitoring.service 2>&1 | tee -a $LOGFILE

# 주요 파일에 대해 해시 값을 활용한 무결성 검증
echo "Run Integrity Verification"

# foreign ignore setting
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; SET GLOBAL foreign_key_checks=0;" 2>&1 | tee -a $LOGFILE

# Integrity Verification 실행
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; CREATE TABLE IF NOT EXISTS integrity_verification_initial_hash (id bigint unsigned NOT NULL AUTO_INCREMENT, mshost_id bigint unsigned NOT NULL COMMENT 'the ID of the mshost', file_path varchar(255) NOT NULL COMMENT 'the file path for integrity verification', initial_hash_value varchar(255) COMMENT 'the initial hash value of the file', comparison_hash_value varchar(255) COMMENT 'the hash value for file comparison', verification_result tinyint(1) DEFAULT 1 COMMENT 'check executions success or failure', verification_date datetime DEFAULT NULL COMMENT 'the last verification time', verification_details blob COMMENT 'verification result detailed message', PRIMARY KEY (id), UNIQUE KEY i_integrity_verify__mshost_id__file_path (mshost_id,file_path), KEY i_integrity_verify__mshost_id (mshost_id), CONSTRAINT fk_integrity_verify__mshost_id FOREIGN KEY (mshost_id) REFERENCES mshost (id) ON DELETE CASCADE) ENGINE=InnoDB CHARSET=utf8mb3;" 2>&1 | tee -a $LOGFILE

UUID=$(cat /proc/sys/kernel/random/uuid)
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO event (uuid, type, state, description, user_id, account_id, domain_id, resource_id, created, level, start_id, archived, display, client_ip) VALUES ('$UUID', 'INTEGRITY.VERIFICATION', 'Started', 'Running integrity verification on management server when running the product.', '2', '2', '1', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'INFO', '0', '0', '1', '$HOST_IP');" 2>&1 | tee -a $LOGFILE

# 주요 파일 초기 해시 값 추출
paths=(
  "/etc/cloudstack/management/config.json"
  "/etc/cloudstack/management/log4j-cloud.xml"
  "/etc/cloudstack/usage/log4j-cloud.xml"
  "/usr/lib/systemd/system/cloudstack-management.service"
  "/usr/lib/systemd/system/cloudstack-usage.service"
  "/usr/lib/systemd/system/mold-monitoring.service"
)
for path in "${paths[@]}"; do
    for file in $(find "$path" -type f); do
        hash_value=$(sha512sum "$file" | awk '{print $1}')
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO integrity_verification_initial_hash (mshost_id, file_path, initial_hash_value, verification_date) VALUES ('1','$file', '$hash_value', DATE_SUB(NOW(), INTERVAL 9 HOUR))" > /dev/null 2>&1
    done
done
# 주요 폴더 하위 파일 초기 해시 값 추출
directories=(
  "/usr/share/cloudstack-usage/"
  "/usr/share/cloudstack-common/"
  "/usr/share/cloudstack-management/"
)
declare -a file_extensions=("jar" "sh" "py")
declare -a file_paths
for directory in "${directories[@]}"; do
    for file_extension in "${file_extensions[@]}"; do
        for files in $(find "$directory" -type f -name "*.$file_extension"); do
            file_paths+=("$files")
        done
    done
done
for file_path in "${file_paths[@]}"; do
    for files in $(find "$file_path" -type f); do
        hash_value=$(sha512sum "$files" | awk '{print $1}')
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO integrity_verification_initial_hash (mshost_id, file_path, initial_hash_value, verification_date) VALUES ('1','$files', '$hash_value', DATE_SUB(NOW(), INTERVAL 9 HOUR))" > /dev/null 2>&1
    done
done

# 주요 파일 비교 해시 값 추출 후, 실패 파일 리스트 업데이트
for path in "${paths[@]}"; do
    for file in $(find "$path" -type f); do
        hash_value=$(sha512sum "$file" | awk '{print $1}')
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; UPDATE integrity_verification_initial_hash SET comparison_hash_value='$hash_value', verification_date=DATE_SUB(NOW(), INTERVAL 9 HOUR) WHERE mshost_id='1' AND file_path='$file';" > /dev/null 2>&1
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; UPDATE integrity_verification_initial_hash SET verification_result = (initial_hash_value = comparison_hash_value);" | tail -n +2
        value="$(mysql --user=root --password=$DATABASE_PASSWD -se "use cloud; SELECT file_path FROM integrity_verification_initial_hash WHERE mshost_id='1' AND file_path='$file' AND verification_result=0;")"
        if [ -n "$value" ]; then
            failed_files+="$value, "
        fi
    done
done
# 파일 비교 해시 값 추출 후, 실패 파일 리스트 업데이트
for file_path in "${file_paths[@]}"; do
    for files in $(find "$file_path" -type f); do
        hash_value=$(sha512sum "$files" | awk '{print $1}')
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; UPDATE integrity_verification_initial_hash SET comparison_hash_value='$hash_value', verification_date=DATE_SUB(NOW(), INTERVAL 9 HOUR) WHERE mshost_id='1' AND file_path='$files';" > /dev/null 2>&1
        mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; UPDATE integrity_verification_initial_hash SET verification_result = (initial_hash_value = comparison_hash_value);" | tail -n +2
        value="$(mysql --user=root --password=$DATABASE_PASSWD -se "use cloud; SELECT file_path FROM integrity_verification_initial_hash WHERE mshost_id='1' AND file_path='$files' AND verification_result=0;")" > /dev/null 2>&1
        if [ -n "$value" ]; then
            failed_files+="$value, "
        fi
    done
done

# Remove the trailing comma from the last element
failed_files="${failed_files%, }"

# final result table 생성
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; CREATE TABLE IF NOT EXISTS integrity_verification_initial_hash_final_result (id bigint unsigned NOT NULL AUTO_INCREMENT, uuid varchar(40) null, mshost_id bigint unsigned NOT NULL COMMENT 'the ID of the mshost', verification_final_result tinyint(1) default 1 not null comment 'check executions success or failure', verification_date datetime DEFAULT NULL COMMENT 'the last verification time', verification_failed_list mediumtext null, type varchar(32) null, PRIMARY KEY (id), UNIQUE KEY i_integrity_verify__mshost_id__final_result (uuid, mshost_id), KEY i_integrity_verify__mshost_id (mshost_id), CONSTRAINT i_integrity_verify__mshost_id__file_path_final_result FOREIGN KEY (mshost_id) REFERENCES mshost (id) ON DELETE CASCADE) ENGINE=InnoDB CHARSET=utf8mb3;" 2>&1 | tee -a $LOGFILE
result=$(mysql --user=root --password=$DATABASE_PASSWD -se "use cloud; SELECT EXISTS(SELECT * FROM integrity_verification_initial_hash WHERE verification_result=0);")
UUID=$(cat /proc/sys/kernel/random/uuid)

# integrity_verification_initial_hash_final_result 데이터 지우기
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; DELETE FROM integrity_verification_initial_hash_final_result" > /dev/null 2>&1

if [ "$result" -eq 1 ]; then
    echo "exists failed files"
    mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO integrity_verification_initial_hash_final_result (uuid, mshost_id, verification_failed_list, verification_final_result, verification_date, type) VALUES ('$UUID', '1','$failed_files', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'Initial')" > /dev/null 2>&1
    UUID=$(cat /proc/sys/kernel/random/uuid)
    mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO alert (uuid, type, pod_id, data_center_id, subject, sent_count, created, last_sent, archived, name) VALUES ('$UUID', '14', '0', '0', 'Management server node integrity verification failed when running the product.', '1', DATE_SUB(NOW(), INTERVAL 9 HOUR), DATE_SUB(NOW(), INTERVAL 9 HOUR), '0', 'ALERT.MANAGEMENT');" 2>&1 | tee -a $LOGFILE
    UUID=$(cat /proc/sys/kernel/random/uuid)
    mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO event (uuid, type, state, description, user_id, account_id, domain_id, resource_id, created, level, start_id, archived, display, client_ip) VALUES ('$UUID', 'INTEGRITY.VERIFICATION', 'Completed', 'Failed to execute integrity verification on the management server when running the product.', '2', '2', '1', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'INFO', '0', '0', '1', '$HOST_IP');" 2>&1 | tee -a $LOGFILE
else
    echo "not exists failed files"
    mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO integrity_verification_initial_hash_final_result (uuid, mshost_id, verification_failed_list, verification_final_result, verification_date, type) VALUES ('$UUID','1','$failed_files', '1', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'Initial')" > /dev/null 2>&1
    UUID=$(cat /proc/sys/kernel/random/uuid)
    mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; INSERT INTO event (uuid, type, state, description, user_id, account_id, domain_id, resource_id, created, level, start_id, archived, display, client_ip) VALUES ('$UUID', 'INTEGRITY.VERIFICATION', 'Completed', 'Successfully completed integrity verification on the management server when running the product.', '2', '2', '1', '0', DATE_SUB(NOW(), INTERVAL 9 HOUR), 'INFO', '0', '0', '1', '$HOST_IP');" 2>&1 | tee -a $LOGFILE
fi

# foreign ignore setting
mysql --user=root --password=$DATABASE_PASSWD -e "use cloud; SET GLOBAL foreign_key_checks=1;" 2>&1 | tee -a $LOGFILE

# DB cloud 계정 외부 접근 차단
mysql --user=root --password=$DATABASE_PASSWD -e "use mysql; delete from mysql.user where host='%' and user='cloud'; flush privileges;"

mv /opt/ABLESTACK-V4.0-4.0.15/tink-1.13.0.jar /usr/share/cloudstack-common/lib/tink-1.13.0.jar
mv /opt/ABLESTACK-V4.0-4.0.15/jetty-maven-plugin-9.4.54.v20240208.jar /usr/share/cloudstack-common/lib/jetty-maven-plugin-9.4.54.v20240208.jar

systemctl disable --now cloudstack-management 2>&1 | tee -a $LOGFILE
echo "Mold install ended!!"  | tee -a $LOGFILE
echo "/opt/ABLESTACK-V4.0-4.0.15/after_setting.sh Please script proceed."  | tee -a $LOGFILE
rm -rf /opt/ABLESTACK-V4.0-4.0.15/bootstrap.sh