mirror of
https://github.com/YunoHost/package_check.git
synced 2024-09-03 20:06:20 +02:00
2273 lines
75 KiB
Bash
2273 lines
75 KiB
Bash
#!/bin/bash
|
|
|
|
echo -e "Loads functions from testing_process.sh"
|
|
|
|
#=================================================
|
|
# Globals variables
|
|
#=================================================
|
|
|
|
# A complete list of backup hooks is available at /usr/share/yunohost/hooks/backup/
|
|
backup_hooks="conf_ssowat data_home conf_ynh_firewall conf_cron"
|
|
|
|
#=================================================
|
|
|
|
break_before_continue () {
|
|
# Make a break if auto_remove is set
|
|
|
|
if [ $auto_remove -eq 0 ] && [ $bash_mode -ne 1 ]
|
|
then
|
|
LXC_CONNECT_INFO # Print access information
|
|
read -p "Press a key to delete the application and continue...." < /dev/tty
|
|
fi
|
|
}
|
|
|
|
check_false_positive_error () {
|
|
# Check if FALSE_ERRORS_DETECTION has detected an false positive error.
|
|
|
|
# We will use
|
|
# check_false_positive_error || return $?
|
|
# to check the result of the function of propagate the result to parent functions.
|
|
|
|
if [ $false_positive_error -eq 1 ] && [ $false_positive_error_loop -lt $max_false_positive_error_loop ]; then
|
|
# Return 75, for EX_TEMPFAIL from sysexits.h
|
|
return 75
|
|
fi
|
|
}
|
|
|
|
#=================================================
|
|
|
|
git_wait_for_pull () {
|
|
local_git_repo="$1"
|
|
min_time_between_pull=$2
|
|
last_pull=$(cat "$local_git_repo/last_pull")
|
|
last_pull=${last_pull:-0}
|
|
|
|
if [ $(( $(date +%s) - $last_pull )) -ge $min_time_between_pull ]
|
|
then
|
|
date +%s > "$local_git_repo/last_pull"
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
#=================================================
|
|
|
|
# In complement of all checks done by Linter, check if the template is respected.
|
|
CHECK_TEMPLATE () {
|
|
|
|
template_error=0
|
|
app_scripts_dir="$package_path/scripts"
|
|
# For some check, we don't want to look at the standard scripts.
|
|
app_scripts="backup|change_url|config|install|remove|restore|upgrade"
|
|
|
|
grep_command="grep --extended-regexp --dereference-recursive --line-number"
|
|
grep_ignore_scripts="grep --invert-match --extended-regexp $app_scripts"
|
|
|
|
show_error () {
|
|
messageL1="$1"
|
|
messageL2="$2"
|
|
messageL3="$3"
|
|
# Keep only the first line found as evidence
|
|
evidence="$(echo "$template_output" | head --lines=1)"
|
|
evidence="${evidence##$package_path/}"
|
|
if [ -n "$template_output" ]
|
|
then
|
|
if [ $template_error -eq 0 ]
|
|
then
|
|
all_test=$((all_test+1))
|
|
unit_test_title "Compare the syntax to the packaging template..."
|
|
|
|
ECHO_FORMAT "\nLooks like your package does not respect the template of the example app...\n" "red" "bold"
|
|
ECHO_FORMAT "Please follow the template https://github.com/YunoHost/example_ynh\n\n" "lyellow"
|
|
fi
|
|
template_error=1
|
|
|
|
ECHO_FORMAT "\n$messageL1\n" "red" "bold"
|
|
if [ -n "$messageL2" ]; then
|
|
ECHO_FORMAT "$messageL2\n" "red" "bold"
|
|
fi
|
|
if [ -n "$messageL3" ]; then
|
|
ECHO_FORMAT "$messageL3\n" "red" "bold"
|
|
fi
|
|
ECHO_FORMAT "Here the culprit:\n" "red" "bold"
|
|
ECHO_FORMAT "$evidence\n" "lyellow"
|
|
fi
|
|
}
|
|
|
|
### Detect common functions that are not helpers
|
|
template_output="$($grep_command "^[[:blank:]]*[[:alnum:][:punct:]]+[[:blank:]]*\([[:blank:]]*\)" "$app_scripts_dir" | $grep_ignore_scripts)"
|
|
# Put aside ynh_ like helpers
|
|
helper_like="$(echo "$template_output" | sed -n '/:[[:blank:]]*ynh_/p')"
|
|
# Remove ynh_ like helpers
|
|
template_output="$(echo "$template_output" | sed '/:[[:blank:]]*ynh_/d')"
|
|
|
|
# Ignore known functions
|
|
# Remove find_mails, which is a part of ynh_send_readme_to_admin
|
|
template_output="$(echo "$template_output" | sed '/find_mails/d')"
|
|
# And at_least_one, part of ynh_get_scalable_phpfpm
|
|
template_output="$(echo "$template_output" | sed '/at_least_one/d')"
|
|
show_error "Do not use specific functions aside of ynh helpers." "Keep your code linear directly into the scripts to ease the reading of your scripts"
|
|
|
|
# Ignore known helpers
|
|
# Remove ynh_clean_setup, an official helper defined only in comment into official helpers
|
|
helper_like="$(echo "$helper_like" | sed '/ynh_clean_setup/d')"
|
|
|
|
### Detect functions that looks like YunoHost helpers
|
|
if [ -n "$helper_like" ]
|
|
then
|
|
# Download official helpers and YunoHost helpers
|
|
# Get officials helpers
|
|
official_helper_dir="$script_dir/helpers/Officials"
|
|
mkdir -p "$official_helper_dir"
|
|
( cd "$official_helper_dir"
|
|
# If we don't already have the .git directory
|
|
if [ ! -d .git ]
|
|
then
|
|
# Set the git clone
|
|
git init > /dev/null 2>&1
|
|
git remote add origin -f https://github.com/YunoHost/yunohost > /dev/null 2>&1
|
|
git config core.sparseCheckout true
|
|
# Get only the helper directory
|
|
echo "/data/helpers.d" > .git/info/sparse-checkout
|
|
fi
|
|
# To not pull more than once a hour
|
|
if git_wait_for_pull "$official_helper_dir" 3600; then
|
|
git pull origin HEAD > /dev/null 2>&1
|
|
fi )
|
|
|
|
# And get experimentals helpers
|
|
experimental_helper_dir="$script_dir/helpers/Experimental_helpers"
|
|
( cd "$script_dir/helpers"
|
|
# If we don't already have the repository
|
|
if [ ! -d Experimental_helpers ]
|
|
then
|
|
# Clone the repository
|
|
git clone https://github.com/YunoHost-Apps/Experimental_helpers > /dev/null 2>&1
|
|
fi
|
|
cd Experimental_helpers
|
|
# To not pull more than once a hour
|
|
if git_wait_for_pull "$experimental_helper_dir" 3600; then
|
|
git pull origin HEAD > /dev/null 2>&1
|
|
fi )
|
|
|
|
# Check each helper found
|
|
while read helper
|
|
do
|
|
# Keep only the name of the helper
|
|
helper_name=$(echo "$helper" | sed 's/.*:\([[:alnum:][:punct:]]*\).*/\1/' | sed 's/()//')
|
|
|
|
# Try to find the helper whether in officials or experimentals
|
|
if ! $grep_command --quiet "^$helper_name" "$script_dir/helpers"
|
|
then
|
|
template_output="$helper"
|
|
show_error "This helper does not look like an existing helper." "Do not use specific functions aside of ynh helpers." "Keep your code linear directly into the scripts to ease the reading of your scripts"
|
|
break
|
|
fi
|
|
done <<< "$(echo "$helper_like")"
|
|
fi
|
|
|
|
|
|
### Detect usage of ynh_render_template
|
|
template_output="$($grep_command --word-regexp "ynh_render_template" "$app_scripts_dir")"
|
|
show_error "Do not use ynh_render_template in app scripts." "Use ynh_replace_string instead to keep clear all modifications made on files"
|
|
|
|
|
|
### Detect presence of comment separators
|
|
for script in ${app_scripts//|/ }
|
|
do
|
|
if [ -e "$app_scripts_dir/$script" ]
|
|
then
|
|
template_output="$($grep_command --count "#=================" "$app_scripts_dir/$script")"
|
|
if [ $template_output -lt 12 ]
|
|
then
|
|
template_output="$app_scripts_dir/$script"
|
|
show_error "Looks like there isn't many comment separators in your script" "Consider adding more separators to clarify the steps in your script"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
|
|
### Detect presence of progression indicators
|
|
for script in ${app_scripts//|/ }
|
|
do
|
|
if [ -e "$app_scripts_dir/$script" ] && [ "$script" != "config" ]
|
|
then
|
|
template_output="$($grep_command --count "ynh_script_progression|ynh_print_info" "$app_scripts_dir/$script")"
|
|
if [ $template_output -lt 5 ] || ( [ "$script" = "change_url" ] && [ $template_output -lt 3 ] )
|
|
then
|
|
template_output="$app_scripts_dir/$script"
|
|
show_error "Looks like there isn't many comment progression indicators in your script" "Consider adding more indicators to help your users know the progression of the scripts"
|
|
fi
|
|
fi
|
|
done
|
|
|
|
|
|
### Detect usage of ynh_restore
|
|
template_output="$($grep_command --word-regexp "ynh_restore" "$app_scripts_dir")"
|
|
show_error "Do not use ynh_restore in app scripts." "Use ynh_restore_file instead to keep clear all files that are restored and in which order."
|
|
|
|
|
|
### Detect usage of set -u or set -e in remove script
|
|
template_output="$($grep_command --word-regexp "set -u|set -e" "$app_scripts_dir/remove")"
|
|
show_error "Do not use 'set -e' or 'set -u' in a remove script." "If an error happen during the script, the app will be half removed !"
|
|
|
|
if [ $template_error -eq 1 ]
|
|
then
|
|
echo ""
|
|
RESULT_template=1
|
|
check_failed
|
|
fi
|
|
}
|
|
|
|
#=================================================
|
|
|
|
PRINT_YUNOHOST_VERSION () {
|
|
ECHO_FORMAT ">> YunoHost versions:\n" "white" "bold" clog
|
|
# Be sure that the container is running
|
|
LXC_START "true"
|
|
# Print the version of YunoHost from the LXC container
|
|
ssh $arg_ssh $lxc_name "sudo yunohost --version"
|
|
|
|
# Get the version of YunoHost from the LXC container
|
|
ynh_version=$(ssh -q $lxc_name "sudo yunohost --version --output-as plain | grep -A4 moulinette | tail -n1 | sed 's@\.@@g' | cut -d+ -f1")
|
|
}
|
|
|
|
#=================================================
|
|
# Install and remove an app
|
|
#=================================================
|
|
|
|
SETUP_APP () {
|
|
# Install an application in a LXC container
|
|
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
|
|
# Exec the pre-install instruction, if there one
|
|
if [ -n "$pre_install" ]
|
|
then
|
|
ECHO_FORMAT "Pre installation request\n" "white" "bold" clog
|
|
# Start the lxc container
|
|
LXC_START "true"
|
|
# Copy all the instructions into a script
|
|
echo "$pre_install" > "$script_dir/preinstall.sh"
|
|
chmod +x "$script_dir/preinstall.sh"
|
|
# Replace variables
|
|
sed -i "s/\$USER/$test_user/" "$script_dir/preinstall.sh"
|
|
sed -i "s/\$DOMAIN/$main_domain/" "$script_dir/preinstall.sh"
|
|
sed -i "s/\$SUBDOMAIN/$sub_domain/" "$script_dir/preinstall.sh"
|
|
sed -i "s/\$PASSWORD/$yuno_pwd/" "$script_dir/preinstall.sh"
|
|
# Copy the pre-install script into the container.
|
|
scp -rq "$script_dir/preinstall.sh" "$lxc_name":
|
|
# Then execute the script to execute the pre-install commands.
|
|
LXC_START "./preinstall.sh >&2"
|
|
# Print the log to print the results
|
|
ECHO_FORMAT "$(cat "$temp_log")\n" clog
|
|
fi
|
|
|
|
# Install the application in a LXC container
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app install --force \"$package_dir\" -a \"$manifest_args_mod\""
|
|
|
|
# yunohost_result gets the return code of the installation
|
|
yunohost_result=$?
|
|
|
|
# Print the result of the install command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "Installation successful. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Installation failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
|
|
# Retrieve the app id in the log. To manage the app after
|
|
ynh_app_id=$(sudo tac "$yunohost_log" | grep --only-matching --max-count=1 "YNH_APP_INSTANCE_NAME=[^ ]*" | cut --delimiter='=' --fields=2)
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
}
|
|
|
|
STANDARD_SETUP_APP () {
|
|
# Try to find an existing snapshot for this install, or make an install
|
|
|
|
# If it's a root install
|
|
if [ "$check_path" = "/" ]
|
|
then
|
|
# Check if a snapshot already exist for this install
|
|
if [ -z "$root_snapshot" ]
|
|
then
|
|
# Make an installation
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Create a snapshot for this installation, to be able to reuse it instead of a new installation.
|
|
# But only if this installation has worked fine
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
# Check if a snapshot already exist for a root install
|
|
if [ -z "$root_snapshot" ]
|
|
then
|
|
ECHO_FORMAT "\nCreate a snapshot for root installation.\n" "white" clog
|
|
create_temp_backup 2
|
|
root_snapshot=snap2
|
|
fi
|
|
fi
|
|
else
|
|
# Or uses an existing snapshot
|
|
ECHO_FORMAT "Uses an existing snapshot for root installation.\n" "white" clog
|
|
use_temp_snapshot $root_snapshot
|
|
fi
|
|
|
|
# In case of sub path install, use another snapshot
|
|
else
|
|
# Check if a snapshot already exist for this install
|
|
if [ -z "$subpath_snapshot" ]
|
|
then
|
|
# Make an installation
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Create a snapshot for this installation, to be able to reuse it instead of a new installation.
|
|
# But only if this installation has worked fine
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
# Check if a snapshot already exist for a subpath (or no_url) install
|
|
if [ -z "$subpath_snapshot" ]
|
|
then
|
|
ECHO_FORMAT "\nCreate a snapshot for sub path installation.\n" "white" clog
|
|
create_temp_backup 1
|
|
root_snapshot=snap1
|
|
fi
|
|
fi
|
|
else
|
|
# Or uses an existing snapshot
|
|
ECHO_FORMAT "Uses an existing snapshot for sub path installation.\n" "white" clog
|
|
use_temp_snapshot $subpath_snapshot
|
|
fi
|
|
fi
|
|
}
|
|
|
|
REMOVE_APP () {
|
|
# Remove an application
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
|
|
ECHO_FORMAT "\nDeleting...\n" "white" "bold" clog
|
|
|
|
# Remove the application from the LXC container
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app remove \"$ynh_app_id\""
|
|
|
|
# yunohost_remove gets the return code of the deletion
|
|
yunohost_remove=$?
|
|
|
|
# Print the result of the remove command
|
|
if [ "$yunohost_remove" -eq 0 ]; then
|
|
ECHO_FORMAT "Deleting successful. ($yunohost_remove)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Deleting failed. ($yunohost_remove)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
}
|
|
|
|
#=================================================
|
|
# Try to access the app by its url
|
|
#=================================================
|
|
|
|
CHECK_URL () {
|
|
# Try to access the app by its url
|
|
|
|
if [ $use_curl -eq 1 ]
|
|
then
|
|
ECHO_FORMAT "\nTry to access by url...\n" "white" "bold"
|
|
|
|
# Force a skipped_uris if public mode is not set
|
|
if [ "$install_type" != "private" ] && [ "$install_type" != "public" ] && [ -z "$public_arg" ]
|
|
then
|
|
# Add a skipped_uris on / for the app
|
|
LXC_START "sudo yunohost app setting \"$ynh_app_id\" skipped_uris -v \"/\""
|
|
# Regen the config of sso
|
|
LXC_START "sudo yunohost app ssowatconf"
|
|
ECHO_FORMAT "Public access forced by a skipped_uris to check.\n" "lyellow" "bold"
|
|
fi
|
|
|
|
# Inform /etc/hosts with the IP of LXC to resolve the domain.
|
|
# This is set only here and not before to prevent to help the app's scripts
|
|
echo -e "$ip_range.2 $main_domain #package_check\n$ip_range.2 $sub_domain #package_check" | sudo tee --append /etc/hosts > /dev/null
|
|
|
|
# Try to resolv the domain during 10 seconds maximum.
|
|
local i=0
|
|
for i in `seq 1 10`; do
|
|
curl --location --insecure $check_domain > /dev/null 2>&1
|
|
# If curl return 6, it's an error "Could not resolve host"
|
|
if [ $? -ne 6 ]; then
|
|
# If not, curl is ready to work.
|
|
break
|
|
fi
|
|
echo -n .
|
|
sleep 1
|
|
done
|
|
|
|
# curl_error indicate the result of curl test
|
|
curl_error=0
|
|
# 503 Service Unavailable can would have some time to work.
|
|
local http503=0
|
|
# yuno_portal equal 1 if the test fall on the portal
|
|
yuno_portal=0
|
|
|
|
# Try to access to the url in 2 times, with a final / and without
|
|
i=1; while [ $i -ne 3 ]
|
|
do
|
|
|
|
# First time, try without final /
|
|
if [ $i -eq 1 ]
|
|
then
|
|
# If the last character is /
|
|
if [ "${check_path: -1}" = "/" ]
|
|
then
|
|
# Remove it
|
|
local curl_check_path="${check_path:0:${#check_path}-1}"
|
|
else
|
|
curl_check_path=$check_path
|
|
fi
|
|
|
|
# The next loop will try the second test
|
|
i=2
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
# Second time, try with the final /
|
|
|
|
# If the last character isn't /
|
|
if [ "${check_path: -1}" != "/" ]
|
|
then
|
|
# Add it
|
|
curl_check_path="$check_path/"
|
|
else
|
|
curl_check_path=$check_path
|
|
fi
|
|
|
|
# The next loop will break the while loop
|
|
i=3
|
|
fi
|
|
|
|
# Remove the previous curl output
|
|
rm -f "$script_dir/url_output"
|
|
|
|
# Call curl to try to access to the url of the app
|
|
curl --location --insecure --silent --show-error --write-out "%{http_code};%{url_effective}\n" $check_domain$curl_check_path --output "$script_dir/url_output" > "$script_dir/curl_print"
|
|
|
|
# Analyze the result of curl command
|
|
if [ $? -ne 0 ]
|
|
then
|
|
ECHO_FORMAT "Connection error...\n" "red" "bold"
|
|
curl_error=1
|
|
fi
|
|
|
|
# Print informations about the connection
|
|
ECHO_FORMAT "Test url: $check_domain$curl_check_path\n" "white"
|
|
ECHO_FORMAT "Real url: $(cat "$script_dir/curl_print" | cut --delimiter=';' --fields=2)\n" "white"
|
|
local http_code=$(cat "$script_dir/curl_print" | cut -d ';' -f1)
|
|
ECHO_FORMAT "HTTP code: $http_code\n" "white"
|
|
|
|
# Analyze the http code
|
|
if [ "${http_code:0:1}" = "0" ] || [ "${http_code:0:1}" = "4" ] || [ "${http_code:0:1}" = "5" ]
|
|
then
|
|
# If the http code is a 0xx 4xx or 5xx, it's an error code.
|
|
curl_error=1
|
|
|
|
# 401 is "Unauthorized", so is a answer of the server. So, it works!
|
|
test "${http_code}" = "401" && curl_error=0
|
|
|
|
# 503 is Service Unavailable, it's a temporary error.
|
|
if [ "${http_code}" = "503" ]
|
|
then
|
|
curl_error=0
|
|
ECHO_FORMAT "Service temporarily unavailable\n" "lyellow" "bold"
|
|
# 3 successive error are allowed
|
|
http503=$(( http503 + 1 ))
|
|
if [ $http503 -ge 3 ]; then
|
|
# Over 3, it's definitively an error
|
|
curl_error=1
|
|
else
|
|
# Below 3 times, retry.
|
|
# Decrease the value of 'i' to retry the same test
|
|
i=$(( i - 1 ))
|
|
# Wait 1 second to let's some time to the 503 error
|
|
sleep 1
|
|
# And retry immediately
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
if [ $curl_error -eq 1 ]; then
|
|
ECHO_FORMAT "The HTTP code show an error.\n" "white" "bold" clog
|
|
fi
|
|
fi
|
|
|
|
# Analyze the output of curl
|
|
if [ -e "$script_dir/url_output" ]
|
|
then
|
|
# Print the title of the page
|
|
local url_title=$(grep "<title>" "$script_dir/url_output" | cut --delimiter='>' --fields=2 | cut --delimiter='<' --fields=1)
|
|
ECHO_FORMAT "Title of the page: $url_title\n" "white"
|
|
|
|
# Check if the page title is neither the YunoHost portail or default nginx page
|
|
if [ "$url_title" = "YunoHost Portal" ]
|
|
then
|
|
ECHO_FORMAT "The connection attempt fall on the YunoHost portal.\n" "white" "bold" clog
|
|
yuno_portal=1
|
|
else
|
|
yuno_portal=0
|
|
if [ "$url_title" = "Welcome to nginx on Debian!" ]
|
|
then
|
|
# Falling on nginx default page is an error.
|
|
curl_error=1
|
|
ECHO_FORMAT "The connection attempt fall on nginx default page.\n" "white" "bold" clog
|
|
fi
|
|
|
|
# Print the first 20 lines of the page
|
|
ECHO_FORMAT "Extract of the page:\n" "white"
|
|
echo -en "\e[37m" # Write in 'light grey'
|
|
lynx -dump -force_html "$script_dir/url_output" | head --lines 20 | tee --append "$test_result"
|
|
echo -e "\e[0m"
|
|
|
|
if [ $show_resources -eq 1 ]
|
|
then
|
|
# Get all the resources for the main page of the app.
|
|
local HTTP_return
|
|
local moved=0
|
|
local ignored=0
|
|
while read HTTP_return
|
|
do
|
|
# Ignore robots.txt and ynhpanel.js. They always redirect to the portal.
|
|
if echo "$HTTP_return" | grep --quiet "$check_domain/robots.txt\|$check_domain/ynhpanel.js"; then
|
|
ECHO_FORMAT "Ressource ignored:" "white"
|
|
ECHO_FORMAT " ${HTTP_return##*http*://}\n"
|
|
ignored=1
|
|
fi
|
|
|
|
# If it's the line with the resource to get
|
|
if echo "$HTTP_return" | grep --quiet "^--.*-- http"
|
|
then
|
|
# Get only the resource itself.
|
|
local resource=${HTTP_return##*http*://}
|
|
|
|
# Else, if would be the HTTP return code.
|
|
else
|
|
# If the return code is different than 200.
|
|
if ! echo "$HTTP_return" | grep --quiet "200 OK$"
|
|
then
|
|
# Skipped the check of ignored ressources.
|
|
if [ $ignored -eq 1 ]
|
|
then
|
|
ignored=0
|
|
continue
|
|
fi
|
|
# Isolate the http return code.
|
|
http_code="${HTTP_return##*awaiting response... }"
|
|
http_code="${http_code:0:3}"
|
|
# If the return code is 301 or 302, let's check the redirection.
|
|
if echo "$HTTP_return" | grep --quiet "30[12] Moved"
|
|
then
|
|
ECHO_FORMAT "Ressource moved:" "white"
|
|
ECHO_FORMAT " $resource\n"
|
|
moved=1
|
|
else
|
|
ECHO_FORMAT "Resource unreachable (Code $http_code)" "red" "bold"
|
|
ECHO_FORMAT " $resource\n"
|
|
# curl_error=1
|
|
moved=0
|
|
fi
|
|
else
|
|
if [ $moved -eq 1 ]
|
|
then
|
|
if echo "$resource" | grep --quiet "/yunohost/sso/"
|
|
then
|
|
ECHO_FORMAT "The previous resource is redirected to the YunoHost portal\n" "red"
|
|
# curl_error=1
|
|
fi
|
|
fi
|
|
moved=0
|
|
fi
|
|
fi
|
|
done <<< "$(cd "$package_path"; LC_ALL=C wget --adjust-extension --page-requisites --no-check-certificate $check_domain$curl_check_path 2>&1 | grep "^--.*-- http\|^HTTP request sent")"
|
|
fi
|
|
echo ""
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Detect the issue alias_traversal, https://github.com/yandex/gixy/blob/master/docs/en/plugins/aliastraversal.md
|
|
|
|
# Create a file to get for alias_traversal
|
|
echo "<!DOCTYPE html><html><head>
|
|
<title>alias_traversal test</title>
|
|
</head><body><h1>alias_traversal test</h1>
|
|
If you see this page, you have failed the test for alias_traversal issue.</body></html>" \
|
|
| sudo tee /var/lib/lxc/$lxc_name/rootfs/var/www/html/alias_traversal.html > /dev/null
|
|
|
|
curl --location --insecure --silent $check_domain$check_path../html/alias_traversal.html \
|
|
| grep "title" | grep --quiet "alias_traversal test" \
|
|
&& ECHO_FORMAT "Issue alias_traversal detected ! Please see here https://github.com/YunoHost/example_ynh/pull/45 to fix that.\n" "red" "bold" && RESULT_alias_traversal=1
|
|
|
|
# Remove the entries in /etc/hosts for the test domain
|
|
sudo sed --in-place '/#package_check/d' /etc/hosts
|
|
else
|
|
# If use_curl is set to 0, the url will not tried
|
|
ECHO_FORMAT "Connexion attempt aborted.\n" "white"
|
|
curl_error=0
|
|
yuno_portal=0
|
|
fi
|
|
}
|
|
|
|
#=================================================
|
|
# Generic functions for unit tests
|
|
#=================================================
|
|
|
|
unit_test_title () {
|
|
# Print a title for the test
|
|
# $1 = Name of the test
|
|
|
|
ECHO_FORMAT "\n\n>> $1 [Test $cur_test/$all_test]\n" "white" "bold" clog
|
|
|
|
# Increment the value of the current test
|
|
cur_test=$((cur_test+1))
|
|
}
|
|
|
|
check_manifest_key () {
|
|
# Check if a manifest key is set
|
|
# $1 = manifest key
|
|
|
|
if [ -z "${1}_arg" ]
|
|
then
|
|
ECHO_FORMAT "Unable to find a manifest key for '${1,,}' in the check_process file. Impossible to perform this test\n" "red" clog
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
replace_manifest_key () {
|
|
# Replace a generic manifest key by another
|
|
# $1 = Manifest key
|
|
# $2 = Replacement value
|
|
|
|
# Build the variable name by concatenate $1 and _arg
|
|
local manifest_key=$(eval echo \$${1}_arg)
|
|
|
|
if [ -n "$manifest_key" ]
|
|
then
|
|
manifest_args_mod=$(echo $manifest_args_mod | sed "s@$manifest_key=[^&]*\&@${manifest_key}=${2}\&@")
|
|
fi
|
|
}
|
|
|
|
check_success () {
|
|
ECHO_FORMAT "--- SUCCESS ---\n" "lgreen" "bold"
|
|
}
|
|
|
|
check_failed () {
|
|
ECHO_FORMAT "--- FAIL ---\n" "red" "bold"
|
|
}
|
|
|
|
check_test_result () {
|
|
# Check the result and print SUCCESS or FAIL
|
|
|
|
if [ $yunohost_result -eq 0 ] && [ $curl_error -eq 0 ] && [ $yuno_portal -eq 0 ]
|
|
then
|
|
check_success
|
|
return 0
|
|
else
|
|
check_failed
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
check_test_result_remove () {
|
|
# Check the result of a remove and print SUCCESS or FAIL
|
|
|
|
if [ $yunohost_remove -eq 0 ]
|
|
then
|
|
check_success
|
|
return 0
|
|
else
|
|
check_failed
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
is_install_failed () {
|
|
# Check if an install have previously work
|
|
|
|
# If the test for install in sub dir isn't desactivated
|
|
sub_dir_install=0
|
|
if [ $setup_sub_dir -ne 0 ]
|
|
then
|
|
# If a test succeed or if force_install_ok is set
|
|
# Or if $setup_sub_dir isn't set in the check_process
|
|
if [ $RESULT_check_sub_dir -eq 1 ] || [ $force_install_ok -eq 1 ] || [ $setup_sub_dir -eq -1 ]
|
|
then
|
|
# Validate installation in sub dir.
|
|
sub_dir_install=1
|
|
fi
|
|
else
|
|
sub_dir_install=0
|
|
fi
|
|
|
|
# If the test for install on root isn't desactivated
|
|
|
|
root_install=0
|
|
if [ $setup_root -ne 0 ] || [ $setup_nourl -eq 1 ]
|
|
then
|
|
# If a test succeed or if force_install_ok is set
|
|
# Or if $setup_root isn't set in the check_process
|
|
if [ $RESULT_check_root -eq 1 ] || [ $force_install_ok -eq 1 ] || [ $setup_root -eq -1 ]
|
|
then
|
|
# Validate installation on root.
|
|
root_install=1
|
|
fi
|
|
else
|
|
root_install=0
|
|
fi
|
|
|
|
if [ $sub_dir_install -eq 0 ] && [ $root_install -eq 0 ]
|
|
then
|
|
ECHO_FORMAT "All installs have failed, impossible to perform this test...\n" "red" clog
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
#=================================================
|
|
# Unit tests
|
|
#=================================================
|
|
|
|
CHECK_SETUP () {
|
|
# Try to install in a sub path, on root or without url access
|
|
# $1 = install type
|
|
|
|
local install_type=$1
|
|
if [ "$install_type" = "subdir" ]; then
|
|
unit_test_title "Installation in a sub path..."
|
|
elif [ "$install_type" = "root" ]; then
|
|
unit_test_title "Installation on the root..."
|
|
else
|
|
unit_test_title "Installation without url access..."
|
|
# Disable the curl test
|
|
use_curl=0
|
|
fi
|
|
|
|
# Check if the needed manifest key are set or abort the test
|
|
if [ "$install_type" != "no_url" ]; then
|
|
check_manifest_key "domain" || return
|
|
check_manifest_key "path" || return
|
|
fi
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
if [ "$install_type" = "subdir" ]; then
|
|
local check_path=$test_path
|
|
elif [ "$install_type" = "root" ]; then
|
|
local check_path=/
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Install the application in a LXC container
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
RESULT_global_setup=1 # Installation succeed
|
|
local check_result_setup=1 # Installation succeed
|
|
else # Fail
|
|
# The global success for a installation can't be failed if another installation succeed
|
|
if [ $RESULT_global_setup -ne 1 ]; then
|
|
RESULT_global_setup=-1 # Installation failed
|
|
fi
|
|
local check_result_setup=-1 # Installation failed
|
|
fi
|
|
|
|
# Create a snapshot for this installation, to be able to reuse it instead of a new installation.
|
|
# But only if this installation has worked fine
|
|
if [ $check_result_setup -eq 1 ]; then
|
|
if [ "$check_path" = "/" ]
|
|
then
|
|
# Check if a snapshot already exist for a root install
|
|
if [ -z "$root_snapshot" ]
|
|
then
|
|
ECHO_FORMAT "Create a snapshot for root installation.\n" "white" clog
|
|
create_temp_backup 2
|
|
root_snapshot=snap2
|
|
fi
|
|
else
|
|
# Check if a snapshot already exist for a subpath (or no_url) install
|
|
if [ -z "$subpath_snapshot" ]
|
|
then
|
|
# Then create a snapshot
|
|
ECHO_FORMAT "Create a snapshot for sub path installation.\n" "white" clog
|
|
create_temp_backup 1
|
|
subpath_snapshot=snap1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Remove the application
|
|
REMOVE_APP
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result_remove
|
|
then # Success
|
|
local check_result_remove=1 # Remove in sub path succeed
|
|
RESULT_global_remove=1 # Remove succeed
|
|
else # Fail
|
|
# The global success for a deletion can't be failed if another remove succeed
|
|
if [ $RESULT_global_remove -ne 1 ]; then
|
|
RESULT_global_remove=-1 # Remove failed
|
|
fi
|
|
local check_result_remove=-1 # Remove in sub path failed
|
|
fi
|
|
|
|
# Reinstall the application after the removing
|
|
# Try to resintall only if the first install is a success.
|
|
if [ $check_result_setup -eq 1 ]
|
|
then
|
|
ECHO_FORMAT "\nReinstall the application after a removing.\n" "white" "bold" clog
|
|
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
local check_result_setup=1 # Installation succeed
|
|
else # Fail
|
|
local check_result_setup=-1 # Installation failed
|
|
fi
|
|
fi
|
|
|
|
# Fill the correct variable depend on the type of test
|
|
if [ "$install_type" = "subdir" ]
|
|
then
|
|
RESULT_check_sub_dir=$check_result_setup
|
|
RESULT_check_remove_sub_dir=$check_result_remove
|
|
else # root and no_url
|
|
RESULT_check_root=$check_result_setup
|
|
RESULT_check_remove_root=$check_result_remove
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
}
|
|
|
|
CHECK_UPGRADE () {
|
|
# Try the upgrade script
|
|
|
|
# Do an upgrade test for each commit in the upgrade list
|
|
while read <&4 commit
|
|
do
|
|
if [ "$commit" == "current" ]
|
|
then
|
|
unit_test_title "Upgrade from the same version..."
|
|
else
|
|
# Get the specific section for this upgrade from the check_process
|
|
extract_section "^; commit=$commit" "^;" "$check_process"
|
|
# Get the name for this upgrade.
|
|
upgrade_name=$(grep "^name=" "$partial_check_process" | cut -d'=' -f2)
|
|
# Or use the commit if there's no name.
|
|
if [ -z "$upgrade_name" ]; then
|
|
unit_test_title "Upgrade from the commit $commit..."
|
|
else
|
|
unit_test_title "Upgrade from $upgrade_name..."
|
|
fi
|
|
fi
|
|
|
|
# Check if an install have previously work
|
|
# Abort if none install worked
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
# Use a path according to previous succeeded installs
|
|
if [ $sub_dir_install -eq 1 ]; then
|
|
local check_path=$test_path
|
|
else
|
|
local check_path=/
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Install the application in a LXC container
|
|
ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog
|
|
if [ "$commit" == "current" ]
|
|
then
|
|
# If no commit is specified, use the current version.
|
|
STANDARD_SETUP_APP
|
|
check_false_positive_error || return $?
|
|
else
|
|
# Otherwise, use a specific commit
|
|
# Backup the modified arguments
|
|
update_manifest_args="$manifest_args_mod"
|
|
# Get the arguments of the manifest for this upgrade.
|
|
manifest_args_mod="$(grep "^manifest_arg=" "$partial_check_process" | cut -d'=' -f2-)"
|
|
if [ -z "$manifest_args_mod" ]; then
|
|
# If there's no specific arguments, use the previous one.
|
|
manifest_args_mod="$update_manifest_args"
|
|
else
|
|
# Otherwise, keep the new arguments, and replace the variables.
|
|
manifest_args_mod="${manifest_args_mod//DOMAIN/$check_domain}"
|
|
manifest_args_mod="${manifest_args_mod//PATH/$check_path}"
|
|
manifest_args_mod="${manifest_args_mod//USER/$test_user}"
|
|
fi
|
|
# Make a backup of the directory
|
|
sudo cp -a "$package_path" "${package_path}_back"
|
|
# Change to the specified commit
|
|
(cd "$package_path"; git checkout --force --quiet "$commit")
|
|
# Install the application
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
# Then replace the backup
|
|
sudo rm -r "$package_path"
|
|
sudo mv "${package_path}_back" "$package_path"
|
|
# And restore the arguments for the manifest
|
|
manifest_args_mod="$update_manifest_args"
|
|
fi
|
|
|
|
# Check if the install had work
|
|
if [ $yunohost_result -ne 0 ]
|
|
then
|
|
ECHO_FORMAT "\nInstallation failed...\n" "red" "bold"
|
|
ECHO_FORMAT "\nUpgrade test ignored...\n" "red" "bold"
|
|
else
|
|
ECHO_FORMAT "\nUpgrade...\n" "white" "bold" clog
|
|
|
|
# Upgrade the application in a LXC container
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app upgrade $ynh_app_id -f \"$package_dir\""
|
|
|
|
# yunohost_result gets the return code of the upgrade
|
|
yunohost_result=$?
|
|
|
|
# Print the result of the upgrade command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "Upgrade successful. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Upgrade failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
# The global success for an upgrade can't be a success if another upgrade failed
|
|
if [ $RESULT_check_upgrade -ne -1 ]; then
|
|
RESULT_check_upgrade=1 # Upgrade succeed
|
|
fi
|
|
else # Fail
|
|
RESULT_check_upgrade=-1 # Upgrade failed
|
|
fi
|
|
|
|
# Remove the application
|
|
REMOVE_APP
|
|
fi
|
|
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
done 4< "$script_dir/upgrade_list"
|
|
}
|
|
|
|
CHECK_PUBLIC_PRIVATE () {
|
|
# Try to install in public or private mode
|
|
# $1 = install type
|
|
|
|
local install_type=$1
|
|
if [ "$install_type" = "private" ]; then
|
|
unit_test_title "Installation in private mode..."
|
|
else [ "$install_type" = "public" ]
|
|
unit_test_title "Installation in public mode..."
|
|
fi
|
|
|
|
# Check if the needed manifest key are set or abort the test
|
|
check_manifest_key "public" || return
|
|
check_manifest_key "public_public" || return
|
|
check_manifest_key "public_private" || return
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
replace_manifest_key "user" "$test_user"
|
|
# Set public or private according to type of test requested
|
|
if [ "$install_type" = "private" ]; then
|
|
replace_manifest_key "public" "$public_private_arg"
|
|
elif [ "$install_type" = "public" ]; then
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
fi
|
|
|
|
# Initialize the value
|
|
local check_result_public_private=0
|
|
|
|
# Try in 2 times, first in root and second in sub path.
|
|
local i=0
|
|
for i in 0 1
|
|
do
|
|
# First, try with a root install
|
|
if [ $i -eq 0 ]
|
|
then
|
|
# Check if root installation worked
|
|
if [ $root_install -eq 1 ]
|
|
then
|
|
# Replace manifest key for path
|
|
local check_path=/
|
|
replace_manifest_key "path" "$check_path"
|
|
else
|
|
# Jump to the second path if this check cannot be do
|
|
ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
fi
|
|
|
|
# Second, try with a sub path install
|
|
elif [ $i -eq 1 ]
|
|
then
|
|
# Check if sub path installation worked, or if force_install_ok is setted.
|
|
if [ $sub_dir_install -eq 1 ]
|
|
then
|
|
# Replace manifest key for path
|
|
local check_path=$test_path
|
|
replace_manifest_key "path" "$check_path"
|
|
else
|
|
# Jump to the second path if this check cannot be do
|
|
ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Install the application in a LXC container
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Change the result according to the results of the curl test
|
|
if [ "$install_type" = "private" ]
|
|
then
|
|
# In private mode, if curl doesn't fell on the ynh portal, it's a fail.
|
|
if [ $yuno_portal -eq 0 ]; then
|
|
ECHO_FORMAT "App is not private: it should redirect to the Yunohost portal, but is publicly accessible instead\n" "lyellow" clog
|
|
yunohost_result=1
|
|
fi
|
|
elif [ "$install_type" = "public" ]
|
|
then
|
|
# In public mode, if curl fell on the ynh portal, it's a fail.
|
|
if [ $yuno_portal -eq 1 ]; then
|
|
ECHO_FORMAT "App page is not public: it should be publicly accessible, but redirects to the Yunohost portal instead\n" "lyellow" clog
|
|
yunohost_result=1
|
|
fi
|
|
fi
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if [ $yunohost_result -eq 0 ] && [ $curl_error -eq 0 ]
|
|
then # Success
|
|
check_success
|
|
# The global success for public/private mode can't be a success if another installation failed
|
|
if [ $check_result_public_private -ne -1 ]; then
|
|
check_result_public_private=1 # Installation succeed
|
|
fi
|
|
else # Fail
|
|
check_failed
|
|
check_result_public_private=-1 # Installation failed
|
|
fi
|
|
|
|
# Fill the correct variable depend on the type of test
|
|
if [ "$install_type" = "private" ]
|
|
then
|
|
RESULT_check_private=$check_result_public_private
|
|
else # public
|
|
RESULT_check_public=$check_result_public_private
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
done
|
|
}
|
|
|
|
CHECK_MULTI_INSTANCE () {
|
|
# Try multi-instance installations
|
|
|
|
unit_test_title "Multi-instance installations..."
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
if [ $sub_dir_install -eq 1 ]; then
|
|
local check_path=$test_path
|
|
else
|
|
local check_path=/
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Install 2 times the same app
|
|
local i=0
|
|
for i in 1 2
|
|
do
|
|
# First installation
|
|
if [ $i -eq 1 ]
|
|
then
|
|
check_domain=$main_domain
|
|
ECHO_FORMAT "First installation: path=$check_domain$check_path\n" clog
|
|
# Second installation
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
check_domain=$sub_domain
|
|
ECHO_FORMAT "Second installation: path=$check_domain$check_path\n" clog
|
|
fi
|
|
|
|
# Replace path and domain manifest keys for the test
|
|
replace_manifest_key "domain" "$check_domain"
|
|
|
|
# Install the application in a LXC container
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Store the result in the correct variable
|
|
# First installation
|
|
if [ $i -eq 1 ]
|
|
then
|
|
local multi_yunohost_result_1=$yunohost_result
|
|
local ynh_app_id_1=$ynh_app_id
|
|
# Second installation
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
local multi_yunohost_result_2=$yunohost_result
|
|
local ynh_app_id_2=$ynh_app_id
|
|
fi
|
|
done
|
|
|
|
# Try to access to the 2 apps by theirs url
|
|
for i in 1 2
|
|
do
|
|
# First app
|
|
if [ $i -eq 1 ]
|
|
then
|
|
check_domain=$main_domain
|
|
ynh_app_id=$ynh_app_id_1
|
|
# Second app
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
check_domain=$sub_domain
|
|
ynh_app_id=$ynh_app_id_2
|
|
fi
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result of curl test
|
|
if [ $curl_error -ne 0 ] || [ $yuno_portal -ne 0 ]
|
|
then
|
|
# The test failed if curl fell on ynh portal or had an error.
|
|
# First app
|
|
if [ $i -eq 1 ]
|
|
then
|
|
multi_yunohost_result_1=1
|
|
# Second app
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
multi_yunohost_result_2=1
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
# Succeed if the 2 installations work;
|
|
if [ $multi_yunohost_result_1 -eq 0 ] && [ $multi_yunohost_result_2 -eq 0 ]
|
|
then # Success
|
|
check_success
|
|
RESULT_check_multi_instance=1
|
|
else # Fail
|
|
check_failed
|
|
RESULT_check_multi_instance=-1
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
}
|
|
|
|
CHECK_COMMON_ERROR () {
|
|
# Try to install with specific complications
|
|
# $1 = install type
|
|
|
|
local install_type=$1
|
|
if [ "$install_type" = "incorrect_path" ]; then
|
|
unit_test_title "Malformed path..."
|
|
# Check if the needed manifest key are set or abort the test
|
|
check_manifest_key "path" || return
|
|
else [ "$install_type" = "port_already_use" ]
|
|
unit_test_title "Port already used..."
|
|
# Check if the needed manifest key are set or abort the test
|
|
check_manifest_key "port" || return
|
|
fi
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Replace path manifest key for the test
|
|
if [ "$install_type" = "incorrect_path" ]; then
|
|
# Change the path from /path to path/
|
|
local wrong_path=${test_path#/}/
|
|
# Use this wrong path only for the arguments that will give to yunohost for installation.
|
|
replace_manifest_key "path" "$wrong_path"
|
|
local check_path=$test_path
|
|
else [ "$install_type" = "port_already_use" ]
|
|
# Use a path according to previous succeeded installs
|
|
if [ $sub_dir_install -eq 1 ]; then
|
|
local check_path=$test_path
|
|
else
|
|
local check_path=/
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
fi
|
|
|
|
# Open the specified port to force the script to find another
|
|
if [ "$install_type" = "port_already_use" ]
|
|
then
|
|
|
|
# If the first character is a #, that means it this port number is not in the manifest
|
|
if [ "${port_arg:0:1}" = "#" ]
|
|
then
|
|
# Retrieve the port number
|
|
local check_port="${port_arg:1}"
|
|
|
|
# Else, the port number is in the manifest. So the port number is set at a fixed value.
|
|
else
|
|
local check_port=6660
|
|
# Replace port manifest key for the test
|
|
replace_manifest_key "port" "$check_port"
|
|
fi
|
|
|
|
# Build a service with netcat for use this port before the app.
|
|
echo -e "[Service]\nExecStart=/bin/netcat -l -k -p $check_port\n
|
|
[Install]\nWantedBy=multi-user.target" | \
|
|
sudo tee "/var/lib/lxc/$lxc_name/rootfs/etc/systemd/system/netcat.service" \
|
|
> /dev/null
|
|
|
|
# Then start this service to block this port.
|
|
LXC_START "sudo systemctl enable netcat & sudo systemctl start netcat"
|
|
fi
|
|
|
|
# Install the application in a LXC container
|
|
SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
local check_result_setup=1
|
|
else # Fail
|
|
local check_result_setup=-1
|
|
fi
|
|
|
|
# Fill the correct variable depend on the type of test
|
|
if [ "$install_type" = "incorrect_path" ]
|
|
then
|
|
RESULT_check_path=$check_result_setup
|
|
elif [ "$install_type" = "port_already_use" ]; then
|
|
RESULT_check_port=$check_result_setup
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
}
|
|
|
|
CHECK_BACKUP_RESTORE () {
|
|
# Try to backup then restore the app
|
|
|
|
unit_test_title "Backup/Restore..."
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Try in 2 times, first in root and second in sub path.
|
|
local i=0
|
|
for i in 0 1
|
|
do
|
|
# First, try with a root install
|
|
if [ $i -eq 0 ]
|
|
then
|
|
# Check if root installation worked, or if force_install_ok is setted.
|
|
if [ $root_install -eq 1 ]
|
|
then
|
|
# Replace manifest key for path
|
|
local check_path=/
|
|
replace_manifest_key "path" "$check_path"
|
|
ECHO_FORMAT "\nPreliminary installation on the root...\n" "white" "bold" clog
|
|
else
|
|
# Jump to the second path if this check cannot be do
|
|
ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
fi
|
|
|
|
# Second, try with a sub path install
|
|
elif [ $i -eq 1 ]
|
|
then
|
|
# Check if sub path installation worked, or if force_install_ok is setted.
|
|
if [ $sub_dir_install -eq 1 ]
|
|
then
|
|
# Replace manifest key for path
|
|
local check_path=$test_path
|
|
replace_manifest_key "path" "$check_path"
|
|
ECHO_FORMAT "\nPreliminary installation in a sub path...\n" "white" "bold" clog
|
|
else
|
|
# Jump to the second path if this check cannot be do
|
|
ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog
|
|
return
|
|
fi
|
|
fi
|
|
|
|
# Install the application in a LXC container
|
|
STANDARD_SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Remove the previous residual backups
|
|
sudo rm -rf /var/lib/lxc/$lxc_name/rootfs/home/yunohost.backup/archives
|
|
sudo rm -rf /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/archives
|
|
|
|
# BACKUP
|
|
# Made a backup if the installation succeed
|
|
if [ $yunohost_result -ne 0 ]
|
|
then
|
|
ECHO_FORMAT "\nInstallation failed...\n" "red" "bold"
|
|
else
|
|
ECHO_FORMAT "\nBackup of the application...\n" "white" "bold" clog
|
|
|
|
# Made a backup of the application
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug backup create -n Backup_test --apps $ynh_app_id --system $backup_hooks"
|
|
|
|
# yunohost_result gets the return code of the backup
|
|
yunohost_result=$?
|
|
|
|
# Print the result of the backup command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "Backup successful. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Backup failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
fi
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if [ $yunohost_result -eq 0 ]
|
|
then # Success
|
|
check_success
|
|
# The global success for a backup can't be a success if another backup failed
|
|
if [ $RESULT_check_backup -ne -1 ]; then
|
|
RESULT_check_backup=1 # Backup succeed
|
|
fi
|
|
else # Fail
|
|
check_failed
|
|
RESULT_check_backup=-1 # Backup failed
|
|
fi
|
|
|
|
# Grab the backup archive into the LXC container, and keep a copy
|
|
sudo cp -a /var/lib/lxc/$lxc_name/rootfs/home/yunohost.backup/archives ./
|
|
|
|
# RESTORE
|
|
# Try the restore process in 2 times, first after removing the app, second after a restore of the container.
|
|
local j=0
|
|
for j in 0 1
|
|
do
|
|
# First, simply remove the application
|
|
if [ $j -eq 0 ]
|
|
then
|
|
# Remove the application
|
|
REMOVE_APP
|
|
|
|
ECHO_FORMAT "\nRestore after removing the application...\n" "white" "bold" clog
|
|
|
|
# Second, restore the whole container to remove completely the application
|
|
elif [ $j -eq 1 ]
|
|
then
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
|
|
# Remove the previous residual backups
|
|
sudo rm -rf /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/archives
|
|
|
|
# Place the copy of the backup archive in the container.
|
|
sudo mv -f ./archives /var/lib/lxcsnaps/$lxc_name/$current_snapshot/rootfs/home/yunohost.backup/
|
|
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
|
|
ECHO_FORMAT "\nRestore on a clean YunoHost system...\n" "white" "bold" clog
|
|
fi
|
|
|
|
# Restore the application from the previous backup
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug backup restore Backup_test --force --apps $ynh_app_id"
|
|
|
|
# yunohost_result gets the return code of the restore
|
|
yunohost_result=$?
|
|
|
|
# Print the result of the backup command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "Restore successful. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Restore failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
CHECK_URL
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
# The global success for a restore can't be a success if another restore failed
|
|
if [ $RESULT_check_restore -ne -1 ]; then
|
|
RESULT_check_restore=1 # Restore succeed
|
|
fi
|
|
else # Fail
|
|
RESULT_check_restore=-1 # Restore failed
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
done
|
|
done
|
|
}
|
|
|
|
CHECK_CHANGE_URL () {
|
|
# Try the change_url script
|
|
|
|
unit_test_title "Change URL..."
|
|
|
|
# Check if the needed manifest key are set or abort the test
|
|
check_manifest_key "domain" || return
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
|
|
# Try in 6 times !
|
|
# Without modify the domain, root to path, path to path and path to root.
|
|
# And then, same with a domain change
|
|
local i=0
|
|
for i in `seq 1 7`
|
|
do
|
|
if [ $i -eq 1 ]; then
|
|
# Same domain, root to path
|
|
check_path=/
|
|
local new_path=$test_path
|
|
local new_domain=$sub_domain
|
|
elif [ $i -eq 2 ]; then
|
|
# Same domain, path to path
|
|
check_path=$test_path
|
|
local new_path=${test_path}_2
|
|
local new_domain=$sub_domain
|
|
elif [ $i -eq 3 ]; then
|
|
# Same domain, path to root
|
|
check_path=$test_path
|
|
local new_path=/
|
|
local new_domain=$sub_domain
|
|
|
|
elif [ $i -eq 4 ]; then
|
|
# Other domain, root to path
|
|
check_path=/
|
|
local new_path=$test_path
|
|
local new_domain=$main_domain
|
|
elif [ $i -eq 5 ]; then
|
|
# Other domain, path to path
|
|
check_path=$test_path
|
|
local new_path=${test_path}_2
|
|
local new_domain=$main_domain
|
|
elif [ $i -eq 6 ]; then
|
|
# Other domain, path to root
|
|
check_path=$test_path
|
|
local new_path=/
|
|
local new_domain=$main_domain
|
|
elif [ $i -eq 7 ]; then
|
|
# Other domain, root to root
|
|
check_path=/
|
|
local new_path=/
|
|
local new_domain=$main_domain
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
|
|
# Ignore the test if it tries to move to the same address
|
|
if [ "$check_path" == "$new_path" ] && [ "$new_domain" == "$sub_domain" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Check if root or subpath installation worked, or if force_install_ok is setted.
|
|
# Try with a sub path install
|
|
if [ "$check_path" = "/" ]
|
|
then
|
|
if [ $root_install -eq 0 ]
|
|
then
|
|
# Jump this test
|
|
ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
elif [ "$new_path" != "/" ] && [ $sub_dir_install -eq 0 ]
|
|
then
|
|
# Jump this test
|
|
ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
fi
|
|
# And with a sub path install
|
|
else
|
|
if [ $sub_dir_install -eq 0 ]
|
|
then
|
|
# Jump this test
|
|
ECHO_FORMAT "Sub path install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
elif [ "$new_path" = "/" ] && [ $root_install -eq 0 ]
|
|
then
|
|
# Jump this test
|
|
ECHO_FORMAT "Root install failed, impossible to perform this test...\n" "lyellow" clog
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
# Install the application in a LXC container
|
|
ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog
|
|
STANDARD_SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
# Check if the install had work
|
|
if [ $yunohost_result -ne 0 ]
|
|
then
|
|
ECHO_FORMAT "Installation failed...\n" "red" "bold"
|
|
else
|
|
ECHO_FORMAT "Change the url from $sub_domain$check_path to $new_domain$new_path...\n" "white" "bold" clog
|
|
|
|
# Change the url
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app change-url $ynh_app_id -d \"$new_domain\" -p \"$new_path\""
|
|
|
|
# yunohost_result gets the return code of the change-url script
|
|
yunohost_result=$?
|
|
|
|
# Print the result of the change_url command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "Change_url script successful. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "Change_url script failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if them still here
|
|
check_witness_files
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
|
|
# Try to access the app by its url
|
|
check_path=$new_path
|
|
check_domain=$new_domain
|
|
CHECK_URL
|
|
fi
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
# The global success for a change_url can't be a success if another change_url failed
|
|
if [ $RESULT_change_url -ne -1 ]; then
|
|
RESULT_change_url=1 # Change_url succeed
|
|
fi
|
|
else # Fail
|
|
RESULT_change_url=-1 # Change_url failed
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
done
|
|
}
|
|
|
|
# Define a function to split a file in multiple parts. Used for actions and config-panel toml
|
|
splitterAA()
|
|
{
|
|
local bound="$1"
|
|
local file="$2"
|
|
|
|
# If $2 is a real file
|
|
if [ -e "$file" ]
|
|
then
|
|
# Replace name of the file by its content
|
|
file="$(cat "$file")"
|
|
fi
|
|
|
|
local file_lenght=$(echo "$file" | wc --lines | awk '{print $1}')
|
|
|
|
bounds=($(echo "$file" | grep --line-number --extended-regexp "$bound" | cut -d':' -f1))
|
|
|
|
# Go for each line number (boundary) into the array
|
|
for line_number in $(seq 0 $(( ${#bounds[@]} -1 )))
|
|
do
|
|
# The first bound is the next line number in the array
|
|
# That the low bound on which we cut
|
|
first_bound=$(( ${bounds[$line_number+1]} - 1 ))
|
|
# If there's no next cell in the array, we got -1, in such case, use the lenght of the file.
|
|
# We cut at the end of the file
|
|
test $first_bound -lt 0 && first_bound=$file_lenght
|
|
# The second bound is the current line number in the array minus the next one.
|
|
# The the upper bound in the file.
|
|
second_bound=$(( ${bounds[$line_number]} - $first_bound - 1 ))
|
|
# Cut the file a first time from the beginning to the first bound
|
|
# And a second time from the end, back to the second bound.
|
|
parts[line_number]="$(echo "$file" | head --lines=$first_bound \
|
|
| tail --lines=$second_bound)"
|
|
done
|
|
}
|
|
|
|
ACTIONS_CONFIG_PANEL () {
|
|
# Try the actions and config-panel features
|
|
|
|
test_type=$1
|
|
if [ "$test_type" == "actions" ]
|
|
then
|
|
unit_test_title "Actions..."
|
|
|
|
toml_file="$package_path/actions.toml"
|
|
if [ ! -e "$toml_file" ]
|
|
then
|
|
ECHO_FORMAT "\nNo actions.toml found !\n" "red" "bold"
|
|
return 1
|
|
fi
|
|
|
|
elif [ "$test_type" == "config_panel" ]
|
|
then
|
|
unit_test_title "Config-panel..."
|
|
|
|
toml_file="$package_path/config_panel.toml"
|
|
if [ ! -e "$toml_file" ]
|
|
then
|
|
ECHO_FORMAT "\nNo config_panel.toml found !\n" "red" "bold"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# Check if the needed manifest key are set or abort the test
|
|
check_manifest_key "domain" || return
|
|
|
|
# Check if an install have previously work
|
|
is_install_failed || return
|
|
|
|
# Copy original arguments
|
|
local manifest_args_mod="$manifest_arguments"
|
|
|
|
# Replace manifest key for the test
|
|
check_domain=$sub_domain
|
|
replace_manifest_key "domain" "$check_domain"
|
|
replace_manifest_key "user" "$test_user"
|
|
replace_manifest_key "public" "$public_public_arg"
|
|
# Use a path according to previous succeeded installs
|
|
if [ $sub_dir_install -eq 1 ]; then
|
|
local check_path=$test_path
|
|
else
|
|
local check_path=/
|
|
fi
|
|
replace_manifest_key "path" "$check_path"
|
|
|
|
# Install the application in a LXC container
|
|
ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog
|
|
STANDARD_SETUP_APP
|
|
check_false_positive_error || return $?
|
|
|
|
validate_action_config_panel()
|
|
{
|
|
# yunohost_result gets the return code of the command
|
|
yunohost_result=$?
|
|
|
|
local message="$1"
|
|
|
|
# Print the result of the command
|
|
if [ $yunohost_result -eq 0 ]; then
|
|
ECHO_FORMAT "$message succeed. ($yunohost_result)\n" "white" clog
|
|
else
|
|
ECHO_FORMAT "$message failed. ($yunohost_result)\n" "white" clog
|
|
fi
|
|
|
|
# Check all the witness files, to verify if they're still there
|
|
check_witness_files
|
|
|
|
# Analyse the log to extract "warning" and "error" lines
|
|
LOG_EXTRACTOR
|
|
check_false_positive_error || return $?
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if check_test_result
|
|
then # Success
|
|
# The global success for a actions can't be a success if another iteration failed
|
|
if [ $RESULT_action_config_panel -ne -1 ]; then
|
|
RESULT_action_config_panel=1 # Actions succeed
|
|
fi
|
|
else # Fail
|
|
RESULT_action_config_panel=-1 # Actions failed
|
|
fi
|
|
|
|
# Make a break if auto_remove is set
|
|
break_before_continue
|
|
}
|
|
|
|
# List first, then execute
|
|
local i=0
|
|
for i in `seq 1 2`
|
|
do
|
|
# Do a test if the installation succeed
|
|
if [ $yunohost_result -ne 0 ]
|
|
then
|
|
ECHO_FORMAT "\nThe previous test has failed...\n" "red" "bold"
|
|
else
|
|
if [ $i -eq 1 ]
|
|
then
|
|
if [ "$test_type" == "actions" ]
|
|
then
|
|
ECHO_FORMAT "\n> List the available actions...\n" "white" "bold" clog
|
|
|
|
# List the actions
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app action list $ynh_app_id"
|
|
|
|
validate_action_config_panel "yunohost app action list"
|
|
elif [ "$test_type" == "config_panel" ]
|
|
then
|
|
ECHO_FORMAT "\n> Show the config panel...\n" "white" "bold" clog
|
|
|
|
# Show the config-panel
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app config show-panel $ynh_app_id"
|
|
validate_action_config_panel "yunohost app config show-panel"
|
|
fi
|
|
elif [ $i -eq 2 ]
|
|
then
|
|
local parts
|
|
if [ "$test_type" == "actions" ]
|
|
then
|
|
ECHO_FORMAT "\n> Execute the actions...\n" "white" "bold" clog
|
|
|
|
# Split the actions.toml file to separate each actions
|
|
splitterAA "^[[:blank:]]*\[[^.]*\]" "$toml_file"
|
|
elif [ "$test_type" == "config_panel" ]
|
|
then
|
|
ECHO_FORMAT "\n> Apply configurations...\n" "white" "bold" clog
|
|
|
|
# Split the config_panel.toml file to separate each configurations
|
|
splitterAA "^[[:blank:]]*\[.*\]" "$toml_file"
|
|
fi
|
|
|
|
# Read each part, each action, one by one
|
|
for part in $(seq 0 $(( ${#parts[@]} -1 )))
|
|
do
|
|
local action_config_argument_name=""
|
|
local action_config_argument_type=""
|
|
local action_config_argument_default=""
|
|
local actions_config_arguments_specifics=""
|
|
local nb_actions_config_arguments_specifics=1
|
|
|
|
# Ignore part of the config_panel which are only titles
|
|
if [ "$test_type" == "config_panel" ]
|
|
then
|
|
# A real config_panel part should have a `ask = ` line. Ignore the part if not.
|
|
if ! echo "${parts[$part]}" | grep --quiet --extended-regexp "^[[:blank:]]*ask ="
|
|
then
|
|
continue
|
|
fi
|
|
# Get the name of the config. ask = "Config ?"
|
|
local action_config_name="$(echo "${parts[$part]}" | grep "ask *= *" | sed 's/^.* = \"\(.*\)\"/\1/')"
|
|
|
|
# Get the config argument name "YNH_CONFIG_part1_part2.part3.partx"
|
|
local action_config_argument_name="$(echo "${parts[$part]}" | grep "^[[:blank:]]*\[.*\]$")"
|
|
# Remove []
|
|
action_config_argument_name="${action_config_argument_name//[\[\]]/}"
|
|
# And remove spaces
|
|
action_config_argument_name="${action_config_argument_name// /}"
|
|
|
|
elif [ "$test_type" == "actions" ]
|
|
then
|
|
# Get the name of the action. name = "Name of the action"
|
|
local action_config_name="$(echo "${parts[$part]}" | grep "name" | sed 's/^.* = \"\(.*\)\"/\1/')"
|
|
|
|
# Get the action. [action]
|
|
local action_config_action="$(echo "${parts[$part]}" | grep "^\[.*\]$" | sed 's/\[\(.*\)\]/\1/')"
|
|
fi
|
|
|
|
# Check if there's any [action.arguments]
|
|
# config_panel always have arguments.
|
|
if echo "${parts[$part]}" | grep --quiet "$action_config_action\.arguments" || [ "$test_type" == "config_panel" ]
|
|
then local action_config_has_arguments=1
|
|
else local action_config_has_arguments=0
|
|
fi
|
|
# If there's arguments for this action.
|
|
if [ $action_config_has_arguments -eq 1 ]
|
|
then
|
|
if [ "$test_type" == "actions" ]
|
|
then
|
|
# Get the argument [action.arguments.name_of_the_argument]
|
|
action_config_argument_name="$(echo "${parts[$part]}" | grep "$action_config_action\.arguments\." | sed 's/.*\.\(.*\)]/\1/')"
|
|
fi
|
|
|
|
# Get the type of the argument. type = "type"
|
|
action_config_argument_type="$(echo "${parts[$part]}" | grep "type" | sed 's/^.* = \"\(.*\)\"/\1/')"
|
|
# Get the default value of this argument. default = true
|
|
action_config_argument_default="$(echo "${parts[$part]}" | grep "default" | sed 's/^.* = \(.*\)/\1/')"
|
|
# Do not use true or false, use 1/0 instead
|
|
if [ "$action_config_argument_default" == "true" ] && [ "$action_config_argument_type" == "boolean" ]; then
|
|
action_config_argument_default=1
|
|
elif [ "$action_config_argument_default" == "false" ] && [ "$action_config_argument_type" == "boolean" ]; then
|
|
action_config_argument_default=0
|
|
fi
|
|
|
|
if [ "$test_type" == "config_panel" ]
|
|
then
|
|
local check_process_arguments="$config_panel_arguments"
|
|
elif [ "$test_type" == "actions" ]
|
|
then
|
|
local check_process_arguments="$actions_arguments"
|
|
fi
|
|
# Look for arguments into the check_process
|
|
if echo "$check_process_arguments" | grep --quiet "$action_config_argument_name"
|
|
then
|
|
# If there's arguments for this actions into the check_process
|
|
# Isolate the values
|
|
actions_config_arguments_specifics="$(echo "$check_process_arguments" | sed "s/.*$action_config_argument_name=\(.*\)/\1/")"
|
|
# And remove values of the following action
|
|
actions_config_arguments_specifics="${actions_config_arguments_specifics%%\:*}"
|
|
nb_actions_config_arguments_specifics=$(( $(echo "$actions_config_arguments_specifics" | tr --complement --delete "|" | wc --chars) + 1 ))
|
|
fi
|
|
|
|
if [ "$test_type" == "config_panel" ]
|
|
then
|
|
# Finish to format the name
|
|
# Remove . by _
|
|
action_config_argument_name="${action_config_argument_name//./_}"
|
|
# Move all characters to uppercase
|
|
action_config_argument_name="${action_config_argument_name^^}"
|
|
# Add YNH_CONFIG_
|
|
action_config_argument_name="YNH_CONFIG_$action_config_argument_name"
|
|
fi
|
|
fi
|
|
|
|
# Loop on the number of values into the check_process.
|
|
# Or loop once for the default value
|
|
for j in `seq 1 $nb_actions_config_arguments_specifics`
|
|
do
|
|
local action_config_argument_built=""
|
|
if [ $action_config_has_arguments -eq 1 ]
|
|
then
|
|
# If there's values into the check_process
|
|
if [ -n "$actions_config_arguments_specifics" ]
|
|
then
|
|
# Build the argument from a value from the check_process
|
|
local action_config_actual_argument="$(echo "$actions_config_arguments_specifics" | cut -d'|' -f $j)"
|
|
action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\""
|
|
elif [ -n "$action_config_argument_default" ]
|
|
then
|
|
# Build the argument from the default value
|
|
local action_config_actual_argument="$action_config_argument_default"
|
|
action_config_argument_built="--args $action_config_argument_name=\"$action_config_actual_argument\""
|
|
else
|
|
ECHO_FORMAT "\n> No argument into the check_process to use or default argument for \"$action_config_name\"..." "lyellow" "bold" clog
|
|
action_config_actual_argument=""
|
|
fi
|
|
if [ "$test_type" == "config_panel" ]
|
|
then
|
|
ECHO_FORMAT "\n> Apply the configuration for \"$action_config_name\" with the argument \"$action_config_actual_argument\"...\n" "white" "bold" clog
|
|
elif [ "$test_type" == "actions" ]
|
|
then
|
|
ECHO_FORMAT "\n> Execute the action \"$action_config_name\" with the argument \"$action_config_actual_argument\"...\n" "white" "bold" clog
|
|
fi
|
|
else
|
|
ECHO_FORMAT "\n> Execute the action \"$action_config_name\"...\n" "white" "bold" clog
|
|
fi
|
|
|
|
if [ "$test_type" == "config_panel" ]
|
|
then
|
|
# Aply a configuration
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app config apply $ynh_app_id $action_config_action $action_config_argument_built"
|
|
elif [ "$test_type" == "actions" ]
|
|
then
|
|
# Execute an action
|
|
LXC_START "sudo PACKAGE_CHECK_EXEC=1 yunohost --debug app action run $ynh_app_id $action_config_action $action_config_argument_built"
|
|
fi
|
|
validate_action_config_panel "yunohost action $action_config_action"
|
|
done
|
|
done
|
|
fi
|
|
fi
|
|
done
|
|
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
}
|
|
|
|
PACKAGE_LINTER () {
|
|
# Package linter
|
|
|
|
unit_test_title "Package linter..."
|
|
|
|
# Execute package linter and linter_result gets the return code of the package linter
|
|
"$script_dir/package_linter/package_linter.py" "$package_path" > "$temp_result"
|
|
|
|
# linter_result gets the return code of the package linter
|
|
local linter_result=$?
|
|
|
|
# Print the results of package linter and copy these result in the complete log
|
|
cat "$temp_result" | tee --append "$complete_log"
|
|
|
|
# Check the result and print SUCCESS or FAIL
|
|
if [ $linter_result -eq 0 ]
|
|
then # Success
|
|
check_success
|
|
RESULT_linter=1
|
|
else # Fail
|
|
check_failed
|
|
RESULT_linter=-1
|
|
|
|
# If return code is 2, this is critical failure, app should be considered as broken (level 0)
|
|
if [ $linter_result -eq 2 ]
|
|
then
|
|
RESULT_linter=-2
|
|
fi
|
|
fi
|
|
}
|
|
|
|
TEST_LAUNCHER () {
|
|
# Abstract for test execution.
|
|
# $1 = Name of the function to execute
|
|
# $2 = Argument for the function
|
|
|
|
# Intialize values
|
|
yunohost_result=-1
|
|
yunohost_remove=-1
|
|
false_positive_error=0
|
|
max_false_positive_error_loop=3
|
|
|
|
for false_positive_error_loop in $( seq 1 $max_false_positive_error_loop )
|
|
do
|
|
# Start the timer for this test
|
|
start_timer
|
|
# And keep this value separately
|
|
local global_start_timer=$starttime
|
|
|
|
# Execute the test
|
|
$1 $2
|
|
|
|
if [ $false_positive_error -eq 1 ]
|
|
then
|
|
ECHO_FORMAT "This test was aborted because of a $false_positive_error_cond error.\n" "red" "bold" clog
|
|
if [ $false_positive_error_loop -lt $max_false_positive_error_loop ]
|
|
then
|
|
ECHO_FORMAT "The test will restart.\n" "lyellow" "bold" clog
|
|
cur_test=$((cur_test-1))
|
|
fi
|
|
fi
|
|
|
|
# Uses the default snapshot
|
|
current_snapshot=snap0
|
|
|
|
# Stop and restore the LXC container
|
|
LXC_STOP
|
|
|
|
# Restore the started time for the timer
|
|
starttime=$global_start_timer
|
|
# End the timer for the test
|
|
stop_timer 2
|
|
|
|
# Update the lock file with the date of the last finished test.
|
|
# $$ is the PID of package_check itself.
|
|
echo "$1 $2:$(date +%s):$$" > "$lock_file"
|
|
|
|
# Exit the loop if there's no temporary errors detected.
|
|
if [ $false_positive_error -eq 0 ]
|
|
then
|
|
break
|
|
fi
|
|
done
|
|
}
|
|
|
|
set_witness_files () {
|
|
# Create files to check if the remove script does not remove them accidentally
|
|
echo "Create witness files..." | tee --append "$test_result"
|
|
|
|
lxc_dir="/var/lib/lxc/$lxc_name/rootfs"
|
|
|
|
create_witness_file () {
|
|
[ "$2" = "file" ] && local action="touch" || local action="mkdir -p"
|
|
sudo $action "${lxc_dir}${1}"
|
|
}
|
|
|
|
# Nginx conf
|
|
create_witness_file "/etc/nginx/conf.d/$main_domain.d/witnessfile.conf" file
|
|
create_witness_file "/etc/nginx/conf.d/$sub_domain.d/witnessfile.conf" file
|
|
|
|
# /etc
|
|
create_witness_file "/etc/witnessfile" file
|
|
|
|
# /opt directory
|
|
create_witness_file "/opt/witnessdir" directory
|
|
|
|
# /var/www directory
|
|
create_witness_file "/var/www/witnessdir" directory
|
|
|
|
# /home/yunohost.app/
|
|
create_witness_file "/home/yunohost.app/witnessdir" directory
|
|
|
|
# /var/log
|
|
create_witness_file "/var/log/witnessfile" file
|
|
|
|
# Config fpm
|
|
if [ -d "${lxc_dir}/etc/php5/fpm" ]; then
|
|
create_witness_file "/etc/php5/fpm/pool.d/witnessfile.conf" file
|
|
fi
|
|
if [ -d "${lxc_dir}/etc/php/7.0/fpm" ]; then
|
|
create_witness_file "/etc/php/7.0/fpm/pool.d/witnessfile.conf" file
|
|
fi
|
|
|
|
# Config logrotate
|
|
create_witness_file "/etc/logrotate.d/witnessfile" file
|
|
|
|
# Config systemd
|
|
create_witness_file "/etc/systemd/system/witnessfile.service" file
|
|
|
|
# Database
|
|
sudo lxc-attach --name=$lxc_name -- mysqladmin --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") --wait status > /dev/null 2>&1
|
|
sudo lxc-attach --name=$lxc_name -- mysql --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") --wait --execute="CREATE DATABASE witnessdb" > /dev/null 2>&1
|
|
}
|
|
|
|
check_witness_files () {
|
|
# Check all the witness files, to verify if them still here
|
|
|
|
lxc_dir="/var/lib/lxc/$lxc_name/rootfs"
|
|
|
|
check_file_exist () {
|
|
if sudo test ! -e "${lxc_dir}${1}"
|
|
then
|
|
ECHO_FORMAT "The file $1 is missing ! Something gone wrong !\n" "red" "bold"
|
|
RESULT_witness=1
|
|
fi
|
|
}
|
|
|
|
# Nginx conf
|
|
check_file_exist "/etc/nginx/conf.d/$main_domain.d/witnessfile.conf"
|
|
check_file_exist "/etc/nginx/conf.d/$sub_domain.d/witnessfile.conf"
|
|
|
|
# /etc
|
|
check_file_exist "/etc/witnessfile"
|
|
|
|
# /opt directory
|
|
check_file_exist "/opt/witnessdir"
|
|
|
|
# /var/www directory
|
|
check_file_exist "/var/www/witnessdir"
|
|
|
|
# /home/yunohost.app/
|
|
check_file_exist "/home/yunohost.app/witnessdir"
|
|
|
|
# /var/log
|
|
check_file_exist "/var/log/witnessfile"
|
|
|
|
# Config fpm
|
|
if [ -d "${lxc_dir}/etc/php5/fpm" ]; then
|
|
check_file_exist "/etc/php5/fpm/pool.d/witnessfile.conf" file
|
|
fi
|
|
if [ -d "${lxc_dir}/etc/php/7.0/fpm" ]; then
|
|
check_file_exist "/etc/php/7.0/fpm/pool.d/witnessfile.conf" file
|
|
fi
|
|
|
|
# Config logrotate
|
|
check_file_exist "/etc/logrotate.d/witnessfile"
|
|
|
|
# Config systemd
|
|
check_file_exist "/etc/systemd/system/witnessfile.service"
|
|
|
|
# Database
|
|
if ! sudo lxc-attach --name=$lxc_name -- mysqlshow --user=root --password=$(sudo cat "$lxc_dir/etc/yunohost/mysql") | grep --quiet '^| witnessdb' > /dev/null 2>&1
|
|
then
|
|
ECHO_FORMAT "The database witnessdb is missing ! Something gone wrong !\n" "red" "bold"
|
|
RESULT_witness=1
|
|
fi
|
|
if [ $RESULT_witness -eq 1 ]
|
|
then
|
|
yunohost_result=1
|
|
yunohost_remove=1
|
|
fi
|
|
}
|
|
|
|
TESTING_PROCESS () {
|
|
# Launch all tests successively
|
|
|
|
ECHO_FORMAT "\nTests serie: ${tests_serie#;; }\n\n" "white" "underlined" clog
|
|
|
|
PRINT_YUNOHOST_VERSION
|
|
|
|
# Init the value for the current test
|
|
cur_test=1
|
|
|
|
# By default, all tests will try to access the app with curl
|
|
use_curl=1
|
|
|
|
# Check the package with package linter
|
|
if [ $pkg_linter -eq 1 ]; then
|
|
PACKAGE_LINTER
|
|
fi
|
|
|
|
CHECK_TEMPLATE
|
|
|
|
# Try to install in a sub path
|
|
if [ $setup_sub_dir -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_SETUP subdir
|
|
fi
|
|
|
|
# Try to install on root
|
|
if [ $setup_root -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_SETUP root
|
|
fi
|
|
|
|
# Try to install without url access
|
|
if [ $setup_nourl -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_SETUP no_url
|
|
fi
|
|
|
|
# Try the upgrade script
|
|
if [ $upgrade -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_UPGRADE
|
|
fi
|
|
|
|
# Try to install in private mode
|
|
if [ $setup_private -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_PUBLIC_PRIVATE private
|
|
fi
|
|
|
|
# Try to install in public mode
|
|
if [ $setup_public -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_PUBLIC_PRIVATE public
|
|
fi
|
|
|
|
# Try multi-instance installations
|
|
if [ $multi_instance -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_MULTI_INSTANCE
|
|
fi
|
|
|
|
# Try to install with an malformed path
|
|
if [ $incorrect_path -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_COMMON_ERROR incorrect_path
|
|
fi
|
|
|
|
# Try to install with a port already used
|
|
if [ $port_already_use -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_COMMON_ERROR port_already_use
|
|
fi
|
|
|
|
# Try to backup then restore the app
|
|
if [ $backup_restore -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_BACKUP_RESTORE
|
|
fi
|
|
|
|
# Try the change_url script
|
|
if [ $change_url -eq 1 ]; then
|
|
TEST_LAUNCHER CHECK_CHANGE_URL
|
|
fi
|
|
|
|
# Try the actions
|
|
if [ $actions -eq 1 ]; then
|
|
TEST_LAUNCHER ACTIONS_CONFIG_PANEL actions
|
|
fi
|
|
|
|
# Try the config-panel
|
|
if [ $config_panel -eq 1 ]; then
|
|
TEST_LAUNCHER ACTIONS_CONFIG_PANEL config_panel
|
|
fi
|
|
}
|