This commit is contained in:
Alexey Berezhok
2024-03-19 22:05:27 +03:00
commit 346a50856b
1572 changed files with 182163 additions and 0 deletions

151
test/api.bats Normal file
View File

@@ -0,0 +1,151 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
source /tmp/hestia-api-env.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
@test "[Success][ Admin/password ] List users" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "user=admin&password=$password&returncode=no&cmd=v-list-users&arg1=plain" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "admin"
}
@test "[Success][ Hash ] List users" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$apikey&returncode=no&cmd=v-list-users&arg1=plain" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "admin"
}
@test "[Fail][ APIV2 ] Create new user" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$accesskey&returncode=yes&cmd=v-add-user&arg1=hestiatest&arg2=strongpassword&arg3=info@hestiacp.com" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "don't have permission to run the command v-add-user"
}
@test "[Success][ Hash ] Create tmp file" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$apikey&cmd=v-make-tmp-file&arg1=strongpassword&arg2=clusterpassword" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "OK"
}
@test "[Success][ Hash ] Create new user" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$apikey&cmd=v-add-user&arg1=hestiatest&arg2=/tmp/clusterpassword&arg3=info@hestiacp.com&arg4=default" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "OK"
}
@test "[Success][ Hash ] Check password" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$apikey&cmd=v-check-user-password&arg1=hestiatest&arg2=strongpassword" "https://$server:$port/api/index.php"
assert_success
assert_output --partial "OK"
}
@test "[Success][ Local ] Add user" {
run v-add-user hestiatest 1234BCD info@hestiacp.com
assert_success
}
@test "[Success][ Local ] Add DNS domain" {
run v-add-dns-domain hestiatest ilovehestiacp.com 127.0.0.1
assert_success
}
@test "[Success][ APIV2 ] Add remote DNS host" {
run v-add-remote-dns-host $server $port "$accesskey" '' api 'hestiatest'
assert_success
}
@test "[Success][ APIV2 ] Sync DNS cluster 1" {
run v-sync-dns-cluster
assert_success
}
@test "[Success][ Local ] nslookup ilovehestiacp.com" {
run nslookup ilovehestiacp.com $server
assert_success
assert_output --partial "127.0.0.1"
}
@test "[Success][ Local ] Add DNS domain 2" {
run v-add-dns-domain hestiatest ilovehestiacp.org 127.0.0.1
assert_success
}
@test "[Success][ Local ] Add DNS record" {
run v-add-dns-record hestiatest ilovehestiacp.org test A 127.0.0.1 yes 20
assert_success
}
@test "[Success][ Local ] nslookup test.ilovehestiacp.org" {
run nslookup test.ilovehestiacp.org $server
assert_failure 1
assert_output --partial "REFUSED"
run nslookup test.ilovehestiacp.org localhost
assert_success
assert_output --partial "127.0.0.1"
}
@test "[Success][ APIV2 ] Sync DNS cluster 2" {
run v-sync-dns-cluster
assert_success
run nslookup test.ilovehestiacp.org $server
assert_success
assert_output --partial "127.0.0.1"
}
@test "[Success][ Local ] Delete DNS record" {
run v-delete-dns-record hestiatest ilovehestiacp.org 20
assert_success
}
@test "[Success][ Local ] nslookup test.ilovehestiacp.org 2" {
run nslookup test.ilovehestiacp.org $server
assert_success
assert_output --partial "127.0.0.1"
run nslookup test.ilovehestiacp.org localhost
assert_failure
}
@test "[Success][ APIV2 ] Sync DNS cluster 3" {
run v-sync-dns-cluster
assert_success
run nslookup test.ilovehestiacp.org $server
assert_failure
}
@test "[Success][ APIV2 ] Delete remote DNS host" {
run v-delete-remote-dns-host $server
assert_success
}
@test "[Success][ Local ] Delete user" {
run v-delete-user hestiatest
assert_success
}
@test "[Success][ Hash ] Delete user" {
run curl -k -s -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "hash=$apikey&cmd=v-delete-user&arg1=hestiatest" "https://$server:$port/api/index.php"
}

40
test/check_php.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
# Original code: @jroman00 (https://gist.github.com/mathiasverraes/3096500#gistcomment-1575416)
error=false
current=$1
if [ -z "$current" ]; then
current="/usr/local/hestia/web/"
fi
if [ ! -d $current ] && [ ! -f $current ]; then
echo "Invalid directory or file: $current"
error=true
fi
echo "Checking PHP files..."
for file in $(find $current -type f -name "*.php" -not -path "${current}fm/*"); do
RESULTS=$(php -l -n $file)
if [ "$RESULTS" != "No syntax errors detected in $file" ]; then
echo $RESULTS
error=true
fi
done
echo "Checking HTML/PHP combined files..."
for file in $(find $current -type f -name "*.html" -not -path "${current}fm/*"); do
RESULTS=$(php -l -n $file)
if [ "$RESULTS" != "No syntax errors detected in $file" ]; then
echo $RESULTS
error=true
fi
done
if [ "$error" = true ]; then
exit 1
else
exit 0
fi

388
test/checks.bats Normal file
View File

@@ -0,0 +1,388 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
# echo "# Setup_file" > &3
if [ $BATS_TEST_NUMBER = 1 ]; then
echo 'user=test-5285' > /tmp/hestia-test-env.sh
echo 'user2=test-5286' >> /tmp/hestia-test-env.sh
echo 'userbk=testbk-5285' >> /tmp/hestia-test-env.sh
echo 'userpass1=test-5285' >> /tmp/hestia-test-env.sh
echo 'userpass2=t3st-p4ssw0rd' >> /tmp/hestia-test-env.sh
echo 'HESTIA=/usr/local/hestia' >> /tmp/hestia-test-env.sh
echo 'domain=test-5285.hestiacp.com' >> /tmp/hestia-test-env.sh
echo 'domainuk=test-5285.hestiacp.com.uk' >> /tmp/hestia-test-env.sh
echo 'rootdomain=testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'subdomain=cdn.testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'database=test-5285_database' >> /tmp/hestia-test-env.sh
echo 'dbuser=test-5285_dbuser' >> /tmp/hestia-test-env.sh
fi
source /tmp/hestia-test-env.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
@test "is_hash_format_valid accesskey:secret valid" {
run is_hash_format_valid 'bxDaKPyAfLPRgSkoqlkI:Pc8czGPRECp3GxTNMr3LF6zWc8cjfPrNHy_-=A' "hash"
assert_success
}
@test "is_access_key_id_format_valid valid" {
run is_access_key_id_format_valid 'M0ocDoIKbsoXSqtk1mgc' "key"
assert_success
}
@test "is_access_key_id_format_valid short" {
run is_access_key_id_format_valid 'M0ocDoIKbsoXSqtk1mg' "key"
assert_failure $E_INVALID
}
@test "is_access_key_id_format_valid long" {
run is_access_key_id_format_valid 'M0ocDoIKbsoXSqtk1mgca' "key"
assert_failure $E_INVALID
}
@test "is_access_key_id_format_valid non alpha" {
run is_access_key_id_format_valid 'M0ocDoIKbsoX$qtk1mgc' "key"
assert_failure $E_INVALID
}
@test "is_access_key_id_format_valid LHF" {
run is_access_key_id_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_user_format_valid valid" {
run is_user_format_valid 'hxh54SKbALne4s69VsqJRMbMd8Br' "key"
assert_success
}
@test "is_user_format_valid short" {
run is_user_format_valid 'hxh54SKbALne4s69VsqJR' "key"
assert_success
}
@test "is_user_format_valid long" {
run is_user_format_valid 'hxh54SKbALne4s69VsqJRMbMd8Braaa' "key"
assert_failure $E_INVALID
}
@test "is_user_format_valid dash" {
run is_user_format_valid 'hxh54SKbALne4-s6-VsqJRMbMd8Br' "key"
assert_success
}
@test "is_user_format_valid dash repeat" {
run is_user_format_valid 'hxh54SKbALne4s6--VsqJRMbMd8Br' "key"
assert_success
}
@test "is_user_format_valid dash start" {
run is_user_format_valid '-hxh54SKbALne4s6VsqJRMbMd8Br' "key"
assert_failure $E_INVALID
}
@test "is_user_format_valid dash end" {
run is_user_format_valid 'hxh54SKbALne4s6VsqJRMbMd8Br-' "key"
assert_failure $E_INVALID
}
@test "is_user_format_valid LHF" {
run is_user_format_valid 'M0ocDoIK
soXSqtk1mgc' "key"
assert_failure $E_INVALID
}
@test "is_fw_action_format_valid ACCEPT" {
run is_fw_action_format_valid 'ACCEPT' "key"
assert_success
}
@test "is_fw_action_format_valid DROP" {
run is_fw_action_format_valid 'DROP' "key"
assert_success
}
@test "is_fw_action_format_valid TEST" {
run is_fw_action_format_valid 'TEST' "key"
assert_failure $E_INVALID
}
@test "is_fw_action_format_valid LHF" {
run is_fw_protocol_format_valid 'M0ocDoIK
soXSqtk1mgc' "key"
assert_failure $E_INVALID
}
@test "is_fw_protocol_format_valid ICMP" {
run is_fw_protocol_format_valid 'ICMP' "key"
assert_success
}
@test "is_fw_protocol_format_valid UDP" {
run is_fw_protocol_format_valid 'UDP' "key"
assert_success
}
@test "is_fw_protocol_format_valid TCP" {
run is_fw_protocol_format_valid 'TCP' "key"
assert_success
}
@test "is_fw_protocol_format_valid TEST" {
run is_fw_protocol_format_valid 'TEST' "key"
assert_failure $E_INVALID
}
@test "is_domain_format_valid success" {
run is_domain_format_valid 'hestiacp.com' "key"
assert_success
}
@test "is_domain_format_valid www" {
run is_domain_format_valid 'www' "key"
assert_failure $E_INVALID
}
@test "is_domain_format_valid number" {
run is_domain_format_valid '12345' "key"
assert_failure $E_INVALID
}
@test "is_domain_format_valid .." {
run is_domain_format_valid '..' "key"
assert_failure $E_INVALID
}
@test "is_domain_format_valid hestiacp.com." {
run is_domain_format_valid 'mx.hestiacp.com.' "key"
assert_success
}
@test "is_domain_format_valid LF." {
run is_domain_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_dns_record_format_valid" {
rtype='MX'
priority=1;
run is_dns_record_format_valid 'mx.hestiacp.com.'
assert_success
}
@test "is_dns_record_format_valid test" {
rtype='MX'
priority=1;
run is_dns_record_format_valid 'c
1eshutdown
r'
assert_failure $E_INVALID
}
@test "is_alias_format_valid success" {
run is_alias_format_valid 'hestiacp.com' "key"
assert_success
}
@test "is_alias_format_valid success www.domain.com" {
run is_alias_format_valid 'www.hestiacp.com' "key"
assert_success
}
@test "is_alias_format_valid success hestiacp.com,www.hestiacp.com" {
run is_alias_format_valid 'hestiacp.com,www.hestiacp.com' "key"
assert_success
}
@test "is_alias_format_valid success *.hestiacp.com" {
run is_alias_format_valid '*.hestiacp.com' "key"
assert_success
}
@test "is_alias_format_valid success www.hestiacp.com,*.hestiacp.com" {
run is_alias_format_valid 'www.hestiacp.com,*.hestiacp.com' "key"
assert_success
}
@test "is_extention_format_valid test" {
run is_extention_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_string_format_valid test" {
run is_string_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_database_format_valid test" {
run is_database_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_date_format_valid test" {
run is_date_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_dbuser_format_valid test" {
run is_dbuser_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_dns_type_format_valid test" {
run is_dns_type_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_email_format_valid test" {
run is_email_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_fw_port_format_valid test" {
run is_fw_port_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_int_format_valid test" {
run is_int_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_interface_format_valid test" {
run is_interface_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_ip_status_format_valid test" {
run is_ip_status_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_cron_format_valid test" {
run is_cron_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_name_format_valid test" {
run is_name_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_role_valid test" {
run is_role_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_object_format_valid test" {
run is_object_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_common_format_valid test" {
run is_common_format_valid 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "format_no_quotes test2" {
run format_no_quotes 'test bericht' "key"
assert_success
}
@test "format_no_quotes .." {
run format_no_quotes '..' "key"
assert_success
}
@test "format_no_quotes text." {
run format_no_quotes 'text.' "key"
assert_success
}
@test "is_common_format_valid text" {
run is_common_format_valid 'text' "key"
assert_success
}
@test "format_no_quotes test" {
run format_no_quotes 'c
1eshutdown
r' "key"
assert_failure $E_INVALID
}
@test "is_type_valid" {
run is_type_valid 'c
1eshutdown
r' "test,key"
assert_failure $E_INVALID
}
@test "is_command_valid_format v-list-users" {
run is_command_valid_format 'v-list-users'
assert_success
}
@test "is_command_valid_format v-list--users (Fail)" {
run is_command_valid_format 'v-list--users'
assert_failure $E_INVALID
}
@test "is_command_valid_format h-list-users (Fail)" {
run is_command_valid_format 'h-list-users'
assert_failure $E_INVALID
}
@test "is_command_valid_format list-users (Fail)" {
run is_command_valid_format 'list-users'
assert_failure $E_INVALID
}
@test "is_command_valid_format vlist-users (Fail)" {
run is_command_valid_format 'vlist-users'
assert_failure $E_INVALID
}
@test "is_command_valid_format LF (Fail)" {
run is_command_valid_format 'v-
1eshutdown
r' "key"
assert_failure $E_INVALID
}

90
test/config-tests.bats Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
# echo "# Setup_file" > &3
if [ $BATS_TEST_NUMBER = 1 ]; then
echo 'user=test-5285' > /tmp/hestia-test-env.sh
echo 'user2=test-5286' >> /tmp/hestia-test-env.sh
echo 'userbk=testbk-5285' >> /tmp/hestia-test-env.sh
echo 'userpass1=test-5285' >> /tmp/hestia-test-env.sh
echo 'userpass2=t3st-p4ssw0rd' >> /tmp/hestia-test-env.sh
echo 'HESTIA=/usr/local/hestia' >> /tmp/hestia-test-env.sh
echo 'domain=test-5285.hestiacp.com' >> /tmp/hestia-test-env.sh
echo 'domainuk=test-5285.hestiacp.com.uk' >> /tmp/hestia-test-env.sh
echo 'rootdomain=testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'subdomain=cdn.testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'database=test-5285_database' >> /tmp/hestia-test-env.sh
echo 'dbuser=test-5285_dbuser' >> /tmp/hestia-test-env.sh
fi
source /tmp/hestia-test-env.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
@test "Prepare for tests" {
run rm -f /usr/local/hestia/data/templates/web/nginx/php-fpm/*.*
run rm -f /usr/local/hestia/data/templates/web/nginx/*.*
run rm -f /usr/local/hestia/data/templates/web/apache2/php-fpm/*.*
run rm -f /usr/local/hestia/data/templates/web/apache2/*.*
run v-update-web-templates
}
@test "Setup Test domain" {
run v-add-user $user $user $user@hestiacp.com default "Super Test"
assert_success
refute_output
run v-add-web-domain $user 'testhestiacp.com'
assert_success
refute_output
ssl=$(v-generate-ssl-cert "testhestiacp.com" "info@testhestiacp.com" US CA "Orange County" HestiaCP IT "mail.$domain" | tail -n1 | awk '{print $2}')
mv $ssl/testhestiacp.com.crt /tmp/testhestiacp.com.crt
mv $ssl/testhestiacp.com.key /tmp/testhestiacp.com.key
# Use self signed certificates during last test
run v-add-web-domain-ssl $user testhestiacp.com /tmp
assert_success
refute_output
}
@test "Web Config test" {
for template in $(v-list-web-templates plain); do
run v-change-web-domain-tpl $user testhestiacp.com $template
assert_success
refute_output
done
}
@test "Proxy Config test" {
if [ "$PROXY_SYSTEM" = "nginx" ]; then
for template in $(v-list-proxy-templates plain); do
run v-change-web-domain-proxy-tpl $user testhestiacp.com $template
assert_success
refute_output
done
else
skip "Proxy not installed"
fi
}
@test "Clean up" {
run v-delete-user $user
assert_success
refute_output
}

137
test/letsencrypt.bats Normal file
View File

@@ -0,0 +1,137 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
source /tmp/hestia-le-env.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
@test "[ User ] Create new user" {
run v-add-user $user $user $user@hestiacp.com default "Super Test"
assert_success
refute_output
}
@test "[ DNS ]Create DNS domain" {
run v-add-dns-domain $user $domain $ip
assert_success
refute_output
}
@test "[ Web ] Create web domain" {
run v-add-web-domain $user $domain $ip yes "www.$domain,renewal.$domain,foobar.$domain,bar.$domain"
assert_success
refute_output
}
@test "[ Web ] Create 2nd web domain" {
run v-add-web-domain $user "hestia.$domain" $ip yes
assert_success
refute_output
}
@test "[ Web ] Request new certificate for web domain" {
run v-add-letsencrypt-domain $user $domain "www.$domain,renewal.$domain,foobar.$domain,bar.$domain"
assert_success
refute_output
}
@test "[ Web ] Request 2nd new certificate for web domain" {
run v-add-letsencrypt-domain $user "hestia.$domain"
assert_success
refute_output
}
@test "[ Mail ] Create mail domain" {
run v-add-mail-domain $user $domain
assert_success
refute_output
}
@test "[ Mail ] Request new Certificate for Mail Domain" {
run v-add-letsencrypt-domain $user $domain "" "yes"
assert_success
refute_output
}
@test "[ All ] Run renewal script for LE" {
run v-update-letsencrypt-ssl
assert_success
refute_output
}
@test "[ All ] Remove alias and update ssl" {
run v-delete-web-domain-alias $user $domain bar.$domain
assert_success
refute_output
run v-update-letsencrypt-ssl
assert_success
refute_output
}
@test [ Web ] Delete web ssl" {
run v-delete-letsencrypt-domain $user $domain "yes"
assert_success
refute_output
}
@test [ Mail ] Delete mail ssl" {
run v-delete-letsencrypt-domain $user $domain "yes" "yes"
assert_success
refute_output
}
@test "[ Web ] Delete web domain" {
run v-delete-web-domain $user $domain "yes"
assert_success
refute_output
}
@test "[ Redirect ] Create web domain" {
run v-add-web-domain $user "redirect.$domain" $ip yes
assert_success
refute_output
}
@test "[ Redirect ] Add Domain redirect to other website" {
run v-add-web-domain-redirect $user "redirect.$domain" "https://hestiacp.com" 301 "yes"
assert_success
refute_output
}
@test "[ Redirect ] Request new certificate for web {
run v-add-letsencrypt-domain $user "redirect.$domain" ""
assert_success
refute_output
}
@test "[ Redirect ] Run renewal script for LE Redirected domain" {
run v-update-letsencrypt-ssl
assert_success
refute_output
}
@test "Delete user" {
run v-delete-user $user
assert_success
refute_output
}

66
test/lint_script.sh Normal file
View File

@@ -0,0 +1,66 @@
#!/bin/bash
# Includes
# shellcheck source=/usr/local/hestia/conf/hestia.conf
source $HESTIA/conf/hestia.conf
# Variables and arguments
HESTIA="/usr/local/hestia"
script=$1
log=$2
scroll=$3
if [ "$DEBUG_MODE" = "no" ] || [ -z "$DEBUG_MODE" ]; then
echo "ERROR: Developer mode is disabled."
echo "Enable with v-change-sys-config-value DEBUG_MODE yes"
exit 1
fi
if [ -z "$script" ]; then
echo "ERROR: No script specified."
echo "Usage: ./lint_script ~/path/to/bin/v-script-name LOG_OUTPUT"
exit 1
fi
# Install shellcheck
if [ -f /etc/redhat-release ]; then
package_check=$(rpm -qi ShellCheck)
if [ $? -eq 1 ]; then
echo "[ * ] Updating DNF package cache..."
dnf makecache -q > /dev/null 2>&1
echo "[ * ] Installing ShellCheck code linter..."
dnf install -q -y ShellCheck > /dev/null 2>&1
fi
else
package_check=$(dpkg -l | grep shellcheck)
if [ -z "$package_check" ]; then
echo "[ * ] Updating APT package cache..."
apt-get -qq update > /dev/null 2>&1
echo "[ * ] Installing shellcheck code linter..."
apt-get -qq install -y shellcheck > /dev/null 2>&1
fi
fi
# Set debug path and ensure it exists
DEBUG_PATH="$HOME/hst-debug/"
if [ ! -d "$DEBUG_PATH" ]; then
mkdir "$DEBUG_PATH"
fi
# Generate timestamp
time_n_date=$(date +'%F %T')
time_n_date=$(echo $time_n_date | sed "s|:||g" | sed "s| |_|g")
# If logging specified, export shellcheck output to log
if [ "$log" = "yes" ]; then
shellcheck -x "$script" > "$DEBUG_PATH/${script}_$date-$time.log"
else
# Prompt user to scroll output from shellcheck
if [ "$scroll" == "no" ] || [ -z "$scroll" ]; then
clear
shellcheck -x "$script"
else
clear
shellcheck -x "$script" | less
fi
fi

View File

@@ -0,0 +1,460 @@
#!/usr/bin/env php
<?php
#
# Auto create multiple Hesia containers with various features enabled/disabled
# lxc/lxd should be allready configured
# echo "root:1000:1" | sudo tee -a /etc/subuid
# echo "root:1000:1" | sudo tee -a /etc/subgid
#
# - container name will be generated depending on enabled features (os,proxy,webserver and php)
# - 'SHARED_HOST_FOLDER' will be mounted in the (guest lxc) container at '/home/ubuntu/source/' and hestiacp src folder is expected to be there
# - wildcard dns *.hst.domain.tld can be used to point to vm host
# - watch install log ex:(host) tail -n 100 -f /tmp/hst_installer_hst-ub1604-a2-mphp
#
# CONFIG HOST STEPS:
# export SHARED_HOST_FOLDER="/home/myuser/projectfiles"
# mkdir -p $SHARED_HOST_FOLDER
# cd $SHARED_HOST_FOLDER && git clone https://github.com/hestiacp/hestiacp.git && cd hestiacp && git checkout ..branch..
#
/*
# Nginx reverse proxy config: /etc/nginx/conf.d/lxc-hestia.conf
server {
listen 80;
server_name ~(?<lxcname>hst-.+)\.hst\.domain\.tld$;
location / {
set $backend_upstream "http://$lxcname:80";
proxy_pass $backend_upstream;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
server {
listen 8083;
server_name ~^(?<lxcname>hst-.+)\.hst\.domain\.tld$;
location / {
set $backend_upstream "https://$lxcname:8083";
proxy_pass $backend_upstream;
}
}
# use lxc resolver /etc/nginx/nginx.conf
# test resolver ip ex: dig +short @10.240.232.1 hst-ub1804-ngx-a2-mphp
http {
...
resolver 10.240.232.1 ipv6=off valid=5s;
...
}
*/
## Uncomment and configure the following vars
# define('DOMAIN', 'hst.domain.tld');
# define('SHARED_HOST_FOLDER', '/home/myuser/projectfiles');
# define('HST_PASS', ''); // <- # openssl rand -base64 12
# define('HST_EMAIL', 'user@domain.tld');
define("HST_BRANCH", "~localsrc");
define("HST_ARGS", "--force --interactive no --clamav no -p " . HST_PASS . " --email " . HST_EMAIL);
define("LXC_TIMEOUT", 30);
if (
!defined("SHARED_HOST_FOLDER") ||
!defined("HST_PASS") ||
!defined("HST_EMAIL") ||
!defined("HST_BRANCH") ||
!defined("DOMAIN")
) {
die("Error: missing variables" . PHP_EOL);
}
$containers = [
// ['description'=>'hst-d9-ngx-a2-mphp', 'os'=>'debian9', 'nginx'=>true, 'apache2'=>true, 'php'=>'multiphp', 'dns'=>'auto', 'exim'=>'auto'],
[
"description" => "ub1804 ngx mphp",
"os" => "ubuntu18.04",
"nginx" => true,
"apache2" => false,
"php" => "multiphp",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 ngx fpm",
"os" => "ubuntu18.04",
"nginx" => true,
"apache2" => false,
"php" => "fpm",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 ngx a2",
"os" => "ubuntu18.04",
"nginx" => true,
"apache2" => true,
"php" => "auto",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 ngx a2 mphp",
"os" => "ubuntu18.04",
"nginx" => true,
"apache2" => true,
"php" => "multiphp",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 ngx a2 fpm",
"os" => "ubuntu18.04",
"nginx" => true,
"apache2" => true,
"php" => "fpm",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 a2 mphp",
"os" => "ubuntu18.04",
"nginx" => false,
"apache2" => true,
"php" => "multiphp",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 a2 fpm",
"os" => "ubuntu18.04",
"nginx" => false,
"apache2" => true,
"php" => "fpm",
"dns" => "auto",
"exim" => "auto",
],
[
"description" => "ub1804 a2",
"os" => "ubuntu18.04",
"nginx" => false,
"apache2" => true,
"php" => "auto",
"dns" => "auto",
],
[
"description" => "ub1604 a2 mphp",
"os" => "ubuntu16.04",
"nginx" => false,
"apache2" => true,
"php" => "multiphp",
"dns" => "auto",
"exim" => "auto",
],
];
array_walk($containers, function (&$element) {
$lxc_name = "hst-"; // hostname and lxc name prefix. Update nginx reverse proxy config after altering this value
$hst_args = HST_ARGS;
$element["hst_installer"] = "hst-install-ubuntu.sh";
$element["lxc_image"] = "ubuntu:18.04";
if ($element["os"] == "ubuntu16.04") {
$element["lxc_image"] = "ubuntu:16.04";
$lxc_name .= "ub1604";
} elseif ($element["os"] == "debian8") {
$element["lxc_image"] = "images:debian/8";
$element["hst_installer"] = "hst-install-debian.sh";
$lxc_name .= "d8";
} elseif ($element["os"] == "debian9") {
$element["lxc_image"] = "images:debian/9";
$element["hst_installer"] = "hst-install-debian.sh";
$lxc_name .= "d9";
} else {
$lxc_name .= "ub1804";
$element["os"] = "ubuntu18.04";
}
if ($element["nginx"] === true) {
$lxc_name .= "-ngx";
$hst_args .= " --nginx yes";
} else {
$hst_args .= " --nginx no";
}
if ($element["apache2"] === true) {
$lxc_name .= "-a2";
$hst_args .= " --apache yes";
} else {
$hst_args .= " --apache no";
}
if ($element["php"] == "fpm") {
$lxc_name .= "-fpm";
$hst_args .= " --phpfpm yes";
} elseif ($element["php"] == "multiphp") {
$lxc_name .= "-mphp";
$hst_args .= " --multiphp yes";
}
if (isset($element["dns"])) {
if ($element["dns"] === true || $element["dns"] == "auto") {
$hst_args .= " --named yes";
} else {
$hst_args .= " --named no";
}
}
if (isset($element["exim"])) {
if ($element["exim"] === true || $element["exim"] == "auto") {
$hst_args .= " --exim yes";
} else {
$hst_args .= " --exim no";
}
}
if (isset($element["webmail"])) {
if ($element["webmail"] === true || $element["webmail"] == "auto") {
$hst_args .= " --dovecot yes";
} else {
$hst_args .= " --dovecot no";
}
}
$element["lxc_name"] = $lxc_name;
$element["hostname"] = $lxc_name . "." . DOMAIN;
// $hst_args .= ' --with-debs /home/ubuntu/source/hestiacp/src/pkgs/develop/' . $element['os'];
$hst_args .= " --with-debs /tmp/hestiacp-src/debs";
$hst_args .= " --hostname " . $element["hostname"];
$element["hst_args"] = $hst_args;
});
function lxc_run($args, &$rc) {
$cmd_args = "";
if (is_array($args)) {
foreach ($args as $arg) {
$cmd_args .= " " . escapeshellarg($arg);
}
} else {
$cmd_args = $args;
}
exec("lxc " . $cmd_args . " 2>/dev/null", $cmdout, $rc);
if (isset($rc) && $rc !== 0) {
return false;
}
if (json_decode(implode(PHP_EOL, $cmdout), true) === null) {
return $cmdout;
}
return json_decode(implode(PHP_EOL, $cmdout), true);
}
function getHestiaVersion($branch) {
$control_file = "";
if ($branch === "~localsrc") {
$control_file = file_get_contents(SHARED_HOST_FOLDER . "/hestiacp/src/deb/hestia/control");
} else {
$control_file = file_get_contents(
"https://raw.githubusercontent.com/hestiacp/hestiacp/${branch}/src/deb/hestia/control",
);
}
foreach (explode(PHP_EOL, $control_file) as $line) {
if (empty($line)) {
continue;
}
[$key, $value] = explode(":", $line);
if (strtolower($key) === "version") {
return trim($value);
}
}
throw new Exception("Error reading Hestia version for branch: [${branch}]", 1);
}
function get_lxc_ip($name) {
$result = lxc_run(["list", "--format", "csv", "-c", "n,4"], $rc);
if (empty($result)) {
return false;
}
foreach ($result as $line) {
[$cnt, $address] = explode(",", $line);
if ($cnt == $name) {
$iface = explode(" ", $address);
if (filter_var($iface[0], FILTER_VALIDATE_IP)) {
return $iface[0];
} else {
return false;
}
}
}
}
function check_lxc_container($container) {
echo "Check container:" . $container["lxc_name"] . PHP_EOL;
lxc_run(["info", $container["lxc_name"]], $rc);
if (isset($rc) && $rc === 0) {
return;
}
$pid = pcntl_fork();
if ($pid > 0) {
return $pid;
}
echo "Creating container " . $container["lxc_name"] . PHP_EOL;
lxc_run(["init", $container["lxc_image"], $container["lxc_name"]], $rc);
exec(
"lxc config set " .
escapeshellarg($container["lxc_name"]) .
' raw.idmap "both 1000 1000" 2>/dev/null',
$devnull,
$rc,
);
exec(
"lxc config device add " .
escapeshellarg($container["lxc_name"]) .
" hestiasrc disk path=/home/ubuntu/source source=" .
SHARED_HOST_FOLDER .
" 2>/dev/null",
$devnull,
$rc,
);
lxc_run(["start", $container["lxc_name"]], $rc);
$lxc_retry = 0;
do {
$lxc_retry++;
$cip = get_lxc_ip($container["lxc_name"]);
if ($cip) {
echo "Container " . $container["lxc_name"] . " IP: $cip" . PHP_EOL;
}
sleep(1);
} while ($lxc_retry <= LXC_TIMEOUT && filter_var($cip, FILTER_VALIDATE_IP) === false);
echo "Updating container: " . $container["lxc_name"] . PHP_EOL;
exec("lxc exec " . $container["lxc_name"] . " -- apt update", $devnull, $rc);
exit(0);
}
function hst_installer_worker($container) {
$pid = pcntl_fork();
if ($pid > 0) {
return $pid;
}
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "/home/ubuntu/source/hestiacp/src/hst_autocompile.sh --hestia \"' .
HST_BRANCH .
'\" no"',
);
$hver = getHestiaVersion(HST_BRANCH);
echo "Install Hestia ${hver} on " . $container["lxc_name"] . PHP_EOL;
echo "Args: " . $container["hst_args"] . PHP_EOL;
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "cd \"/home/ubuntu/source/hestiacp\"; install/' .
$container["hst_installer"] .
" " .
$container["hst_args"] .
'" 2>&1 > /tmp/hst_installer_' .
$container["lxc_name"],
);
exit(0);
}
// Create and update containers
$worker_pool = [];
foreach ($containers as $container) {
$worker_pid = check_lxc_container($container);
if ($worker_pid > 0) {
$worker_pool[] = $worker_pid;
}
}
echo count($worker_pool) . " LXC workers started" . PHP_EOL;
# waiting for workers to finish
while (count($worker_pool)) {
echo "Wait for LXC workers to finish" . PHP_EOL;
$child_pid = pcntl_wait($status);
if ($child_pid) {
$worker_pos = array_search($child_pid, $worker_pool);
unset($worker_pool[$worker_pos]);
}
}
// Install Hestia
$worker_pool = [];
foreach ($containers as $container) {
# Is hestia installed?
lxc_run("exec " . $container["lxc_name"] . ' -- sudo --login "v-list-sys-config"', $rc);
if (isset($rc) && $rc === 0) {
continue;
}
$worker_pid = hst_installer_worker($container);
if ($worker_pid > 0) {
$worker_pool[] = $worker_pid;
}
}
echo count($worker_pool) . " background workers started" . PHP_EOL;
# waiting for workers to finish
while (count($worker_pool)) {
echo "Wait for workers to finish" . PHP_EOL;
$child_pid = pcntl_wait($status);
if ($child_pid) {
$worker_pos = array_search($child_pid, $worker_pool);
unset($worker_pool[$worker_pos]);
}
}
// Custom config
foreach ($containers as $container) {
echo "Apply custom config on: " . $container["lxc_name"] . PHP_EOL;
# Allow running a reverse proxy in front of Hestia
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "sed -i \'s/session.cookie_secure] = on\$/session.cookie_secure] = off/\' /usr/local/hestia/php/etc/php-fpm.conf"',
);
# get rid off "mesg: ttyname failed: No such device" error
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "sed -i -re \'s/^(mesg n)(.*)$/#\1\2/g\' /root/.profile"',
);
# Use LE sandbox server, prevents hitting rate limits
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "sed -i \'/LE_STAGING/d\' /usr/local/hestia/conf/hestia.conf"',
);
system(
"lxc exec " .
$container["lxc_name"] .
' -- bash -c "echo \'LE_STAGING=\"yes\"\' >> /usr/local/hestia/conf/hestia.conf"',
);
system("lxc exec " . $container["lxc_name"] . ' -- bash -c "service hestia restart"');
}
echo "Hestia containers configured" . PHP_EOL;

591
test/restore.bats Normal file
View File

@@ -0,0 +1,591 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
# echo "# Setup_file" > &3
if [ $BATS_TEST_NUMBER = 1 ]; then
echo 'user=test-5285' > /tmp/hestia-test-env.sh
echo 'user2=test-5286' >> /tmp/hestia-test-env.sh
echo 'userbk=testbk-5285' >> /tmp/hestia-test-env.sh
echo 'userpass1=test-5285' >> /tmp/hestia-test-env.sh
echo 'userpass2=t3st-p4ssw0rd' >> /tmp/hestia-test-env.sh
echo 'HESTIA=/usr/local/hestia' >> /tmp/hestia-test-env.sh
echo 'domain=test-5285.hestiacp.com' >> /tmp/hestia-test-env.sh
echo 'domainuk=test-5285.hestiacp.com.uk' >> /tmp/hestia-test-env.sh
echo 'rootdomain=testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'subdomain=cdn.testhestiacp.com' >> /tmp/hestia-test-env.sh
echo 'database=test-5285_database' >> /tmp/hestia-test-env.sh
echo 'dbuser=test-5285_dbuser' >> /tmp/hestia-test-env.sh
fi
source /tmp/hestia-test-env.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
function validate_web_domain() {
local user=$1
local domain=$2
local webproof=$3
local webpath=${4}
local valwebpath=${5}
refute [ -z "$user" ]
refute [ -z "$domain" ]
refute [ -z "$webproof" ]
source $HESTIA/func/ip.sh
run v-list-web-domain $user $domain
assert_success
USER_DATA=$HESTIA/data/users/$user
local domain_ip=$(get_object_value 'web' 'DOMAIN' "$domain" '$IP')
SSL=$(get_object_value 'web' 'DOMAIN' "$domain" '$SSL')
domain_ip=$(get_real_ip "$domain_ip")
if [ -z $valwebpath ]; then
if [ ! -z $webpath ]; then
domain_docroot=$(get_object_value 'web' 'DOMAIN' "$domain" '$CUSTOM_DOCROOT')
if [ -n "$domain_docroot" ] && [ -d "$domain_docroot" ]; then
assert_file_exist "${domain_docroot}/${webpath}"
else
assert_file_exist "${HOMEDIR}/${user}/web/${domain}/public_html/${webpath}"
fi
fi
fi
# Test HTTP
run curl --location --silent --show-error --insecure --resolve "${domain}:80:${domain_ip}" "http://${domain}/${webpath}"
assert_success
assert_output --partial "$webproof"
# Test HTTPS
if [ "$SSL" = "yes" ]; then
run v-list-web-domain-ssl $user $domain
assert_success
run curl --location --silent --show-error --insecure --resolve "${domain}:443:${domain_ip}" "https://${domain}/${webpath}"
assert_success
assert_output --partial "$webproof"
fi
}
#----------------------------------------------------------#
# Backup / Restore #
#----------------------------------------------------------#
#Test backup
# Hestia v1.1.1 archive contains:
# user: hestia111
# web:
# - test.hestia.com (+SSL self-signed)
# dns:
# - test.hestia.com
# mail:
# - test.hestia.com
# mail acc:
# - testaccount@test.hestia.com
# db:
# - hestia111_db
# cron:
# - 1: /bin/true
# Hestia 1.7.0 archive contains (As zstd format)
# user: hestia131
# web:
# - test.hestia.com (+SSL self-signed)
# FTP Account
# Awstats enabled
# dns:
# - test.hestia.com
# mail:
# - test.hestia.com
# Ratelimit: 10
# mail acc:
# - testaccount@test.hestia.com
# Alias: info@test.hestiacp.com
# Ratelimit: 20
# - support@test.hestia.com
# db:
# - hestia170_db
# cron:
# - 1: /bin/true
# Vesta 0.9.8-23 archive contains:
# user: vesta09823
# web:
# - vesta09823.tld (+SSL self-signed)
# dns:
# - vesta09823.tld
# mail:
# - vesta09823.tld
# mail acc:
# - testaccount@vesta09823.tld
# db:
# - vesta09823_db
# cron:
# - 1: /bin/true
#
# Testing Hestia backups
@test "Restore[1]: Hestia archive for a non-existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
mkdir -p /backup
local archive_name="hestia111.2020-03-26"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[1]: From Hestia [WEB]" {
local domain="test.hestia.com"
validate_web_domain $userbk $domain 'Hello Hestia'
}
@test "Restore[1]: From Hestia [DNS]" {
local domain="test.hestia.com"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[1]: From Hestia [MAIL]" {
local domain="test.hestia.com"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[1]: From Hestia [MAIL-Account]" {
local domain="test.hestia.com"
run v-list-mail-account $userbk $domain testaccount
assert_success
}
@test "Restore[1]: From Hestia [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[1]: From Hestia [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[1]: From Hestia Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}
@test "Restore[2]: Hestia archive over a existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
if [ ! -d "$HOMEDIR/$userbk" ]; then
run v-add-user $userbk $userbk test@hestia.com
assert_success
fi
mkdir -p /backup
local archive_name="hestia111.2020-03-26"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[2]: From Hestia [WEB]" {
local domain="test.hestia.com"
validate_web_domain $userbk "${domain}" 'Hello Hestia'
}
@test "Restore[2]: From Hestia [DNS]" {
local domain="test.hestia.com"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[2]: From Hestia [MAIL]" {
local domain="test.hestia.com"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[2]: From Hestia [MAIL-Account]" {
local domain="test.hestia.com"
run v-list-mail-account $userbk $domain testaccount
assert_success
}
@test "Restore[2]: From Hestia [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[2]: From Hestia [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[2]: From Hestia Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}
@test "Restore[3]: Hestia (zstd) archive for a non-existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
mkdir -p /backup
local archive_name="hestia170.2022-08-23"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[3]: From Hestia [WEB]" {
local domain="test.hestia.com"
validate_web_domain $userbk $domain 'Hello Hestia'
}
@test "Restore[3]: From Hestia [WEB] FTP" {
local domain="test.hestia.com"
assert_file_contains /etc/passwd "$userbk_test"
assert_file_contains /etc/passwd "/home/$userbk/web/$domain"
}
@test "Restore[3]: From Hestia [WEB] Awstats" {
local domain="test.hestia.com"
assert_file_exist /home/$userbk/conf/web/$domain/awstats.conf
}
@test "Restore[3]: From Hestia [WEB] Custom rule" {
# check if custom rule is still working
local domain="test.hestia.com"
validate_web_domain $userbk $domain 'hestia-yes' '/hestia/hestia' 'no'
}
@test "Restore[3]: From Hestia [DNS]" {
local domain="test.hestia.com"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[3]: From Hestia [MAIL]" {
local domain="test.hestia.com"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[3]: From Hestia [MAIL-Account]" {
local domain="test.hestia.com"
run v-list-mail-account $userbk $domain testaccount
assert_success
# Check if alias is created
assert_file_contains /etc/exim4/domains/$domain/aliases "testaccount@$domain"
# Check if expected rate limits are set
assert_file_contains /etc/exim4/domains/$domain/limits "testaccount@$domain:20"
assert_file_contains /etc/exim4/domains/$domain/limits "support@$domain:10"
}
@test "Restore[3]: From Hestia [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[3]: From Hestia [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[3]: From Hestia Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}
@test "Restore[4]: Hestia (zstd) archive for a existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
if [ ! -d "$HOMEDIR/$userbk" ]; then
run v-add-user $userbk $userbk test@hestia.com
assert_success
fi
mkdir -p /backup
local archive_name="hestia170.2022-08-23"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[4]: From Hestia [WEB]" {
local domain="test.hestia.com"
validate_web_domain $userbk $domain 'Hello Hestia'
}
@test "Restore[4]: From Hestia [WEB] FTP" {
local domain="test.hestia.com"
assert_file_contains /etc/passwd "$userbk_test"
assert_file_contains /etc/passwd "/home/$userbk/web/$domain"
}
@test "Restore[4]: From Hestia [WEB] Awstats" {
local domain="test.hestia.com"
assert_file_exist /home/$userbk/conf/web/$domain/awstats.conf
}
@test "Restore[4]: From Hestia [WEB] Custom rule" {
# check if custom rule is still working
local domain="test.hestia.com"
validate_web_domain $userbk $domain 'hestia-yes' '/hestia/hestia' 'no'
}
@test "Restore[4]: From Hestia [DNS]" {
local domain="test.hestia.com"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[4]: From Hestia [MAIL]" {
local domain="test.hestia.com"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[4]: From Hestia [MAIL-Account]" {
local domain="test.hestia.com"
run v-list-mail-account $userbk $domain testaccount
assert_success
# Check if alias is created
assert_file_contains /etc/exim4/domains/$domain/aliases "testaccount@$domain"
# Check if expected rate limits are set
assert_file_contains /etc/exim4/domains/$domain/limits "testaccount@$domain:20"
assert_file_contains /etc/exim4/domains/$domain/limits "support@$domain:10"
}
@test "Restore[4]: From Hestia [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[4]: From Hestia [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[4]: From Hestia Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}
# Testing Vesta Backups
@test "Restore[1]: Vesta archive for a non-existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
mkdir -p /backup
local archive_name="vesta09823.2018-10-18"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[1]: From Vesta [WEB]" {
local domain="vesta09823.tld"
validate_web_domain $userbk $domain 'Hello Vesta'
}
@test "Restore[1]: From Vesta [DNS]" {
local domain="vesta09823.tld"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[1]: From Vesta [MAIL]" {
local domain="vesta09823.tld"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[1]: From Vesta [MAIL-Account]" {
local domain="vesta09823.tld"
run v-list-mail-account $userbk $domain testaccount
assert_success
}
@test "Restore[1]: From Vesta [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[1]: From Vesta [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[1]: From Vesta Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}
@test "Restore[2]: Vesta archive over a existing user" {
if [ -d "$HOMEDIR/$userbk" ]; then
run v-delete-user $userbk
assert_success
refute_output
fi
if [ ! -d "$HOMEDIR/$userbk" ]; then
run v-add-user $userbk $userbk test@hestia.com
assert_success
fi
mkdir -p /backup
local archive_name="vesta09823.2018-10-18"
run wget --quiet --tries=3 --timeout=15 --read-timeout=15 --waitretry=3 --no-dns-cache "https://storage.hestiacp.com/testing/data/${archive_name}.tar" -O "/backup/${archive_name}.tar"
assert_success
run v-restore-user $userbk "${archive_name}.tar"
assert_success
rm "/backup/${archive_name}.tar"
}
@test "Restore[2]: From Vesta [WEB]" {
local domain="vesta09823.tld"
validate_web_domain $userbk "${domain}" 'Hello Vesta'
}
@test "Restore[2]: From Vesta [DNS]" {
local domain="vesta09823.tld"
run v-list-dns-domain $userbk $domain
assert_success
run nslookup $domain 127.0.0.1
assert_success
}
@test "Restore[2]: From Vesta [MAIL]" {
local domain="vesta09823.tld"
run v-list-mail-domain $userbk $domain
assert_success
}
@test "Restore[2]: From Vesta [MAIL-Account]" {
local domain="vesta09823.tld"
run v-list-mail-account $userbk $domain testaccount
assert_success
}
@test "Restore[2]: From Vesta [DB]" {
run v-list-database $userbk "${userbk}_db"
assert_success
}
@test "Restore[2]: From Vesta [CRON]" {
run v-list-cron-job $userbk 1
assert_success
}
@test "Restore[2]: From Vesta Cleanup" {
run v-delete-user $userbk
assert_success
refute_output
}

43
test/shellcheck.sh Executable file
View File

@@ -0,0 +1,43 @@
#!/bin/sh
# Note use sh and not bash!
# To be used with in shellcheck and automated usage
# Generate timestamp
# If logging specified, export shellcheck output to log
# Excluded codes
# SC2086 = SC2086: Double quote to prevent globbing and word splitting. - Keep it more readable please use them with v-xxx-commands when used user input might be not validated corrections and whitespaces might cause a risk
# SC2002: Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
# Check exit code directly with e.g. 'if mycmd;', not indirectly with $?. Might be worth disable in in the future
# SC2181: Check exit code directly with e.g. 'if mycmd;', not indirectly with $?.
# SC2153: Possible misspelling: DOMAIN may not be assigned, but domain is. - Issues with SOURCE importing vars that are not defined in the script it self but config files
# SC2016: Expressions don't expand in single quotes, use double quotes for that. - History reasons
# SC2196: egrep is non-standard and deprecated. Use grep -E instead. Todo be removed in the future
# SC1090; Can't follow non-constant source. Use a directive to specify location. - Hestia loves $HESTIA/data/ips/$ip
# SC2031: var was modified in a subshell. That change might be lost.
# SC2010
# SC2143
# SC2046
#set default value for error
err=0
shellcheck --version
i=0
f=0
files=$(grep -rlE '#!/bin/(bash|sh)' ./ | grep -vE '\.(git|j2$|md$)')
for file in $files; do
i=$(($i + 1))
shellcheck -x "$file" --severity="error"
# Only show failed checks
if [ $? -gt 0 ]; then
f=$(($f + 1))
echo "Linting: $file"
printf "%s: \033[0;31m Fail \033[0m\n" "$file"
err=1
fi
done
echo "$i files checked and $f errors"
exit $err

2239
test/test.bats Executable file

File diff suppressed because it is too large Load Diff

52
test/wildcard.bats Normal file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bats
if [ "${PATH#*/usr/local/hestia/bin*}" = "$PATH" ]; then
. /etc/profile.d/hestia.sh
fi
load 'test_helper/bats-support/load'
load 'test_helper/bats-assert/load'
load 'test_helper/bats-file/load'
function random() {
head /dev/urandom | tr -dc 0-9 | head -c$1
}
function setup() {
source /tmp/wildcard.sh
source $HESTIA/func/main.sh
source $HESTIA/conf/hestia.conf
source $HESTIA/func/ip.sh
}
# User and domain needs to already exists as dns domain due to DNS
@test "[ Web ] Create web domain" {
run v-add-web-domain $user $domain $ip yes "*.$domain"
assert_success
refute_output
}
@test "[ Web ] Request new certificate for web domain" {
run v-restart-web
run v-add-letsencrypt-domain $user $domain "*.$domain"
assert_success
refute_output
}
@test "[ All ] Run renewal script for LE" {
run v-update-letsencrypt-ssl
assert_success
refute_output
run openssl x509 -text -in /usr/local/hestia/data/users/$user/ssl/$domain.crt
assert_success
assert_output --partial "*.$domain"
}
@test "[ Web ] Delete web domain" {
run v-delete-web-domain $user $domain "yes"
assert_success
refute_output
}