diff --git a/demo_lxc_build.sh b/demo_lxc_build.sh index d392ce9..84a2985 100755 --- a/demo_lxc_build.sh +++ b/demo_lxc_build.sh @@ -69,7 +69,7 @@ ynh_lxc_run_inside --name="$lxc_name1" --command="yunohost -v" | tee -a "$LOG_BU # ******** ynh_print_info --message="> Modification de Yunohost pour la demo" | tee -a "$LOG_BUILD_LXC" 2>&1 -if [ ${FOR_PACKAGE_CHECK:-0} -eq 1 ]; then +if [ ${DONT_INSTALL_FOR_NOW:-0} -eq 1 ]; then # App officielles ynh_print_info --message="> Installation des applications officielles" | tee -a "$LOG_BUILD_LXC" 2>&1 # Ampache diff --git a/ynh_lxd b/ynh_lxd new file mode 100644 index 0000000..5e6abe7 --- /dev/null +++ b/ynh_lxd @@ -0,0 +1,981 @@ +#!/bin/bash + +#================================================= +# LXC helpers +#================================================= + +# Check if a LXC container exists +# +# usage: ynh_lxc_exists --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_exists() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ! lxc list --format json | jq -e --arg name $name '.[] | select(.name==$name) | .name' >/dev/null + then + return 1 + else + return 0 + fi +} + +# Return LXC container status +# +# usage: ynh_lxc_status --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_status() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_exists --name=$name + then + lxc list --format json | jq -r --arg name $name '.[] | select(.name==$name) | .state | .status' + fi +} + +# Check if an LXC container is running +# +# usage: ynh_lxc_is_started --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_is_started() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if [ "$(ynh_lxc_status --name=$name)" == Running ] + then + return 0 + else + return 1 + fi +} + +# Check if an LXC container is stopped +# +# usage: ynh_lxc_is_stopped --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_is_stopped() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if [ "$(ynh_lxc_status --name=$name)" == Stopped ] + then + return 0 + else + return 1 + fi +} + +# Start an LXC container +# +# usage: ynh_lxc_start --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_start() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # If the container exists + if ynh_lxc_exists --name=$name + then + if ! ynh_lxc_is_started --name=$name + then + lxc start $name + fi + fi +} + +# Stopping an LXC container +# +# usage: ynh_lxc_stop --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_stop() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # If the container exists + if ynh_lxc_exists --name=$name + then + ynh_print_info --message="Stopping LXC $name" + wait_period=0 + while ! ynh_lxc_is_stopped --name=$name + do + lxc stop $name + wait_period=$(($wait_period+10)) + if [ $wait_period -gt 30 ];then + break + else + sleep 1 + fi + done + + # If the command times out, then add the option --force + wait_period=0 + while ! ynh_lxc_is_stopped --name=$name + do + lxc stop $name --force + wait_period=$(($wait_period+10)) + if [ $wait_period -gt 30 ];then + break + else + sleep 5 + fi + done + fi +} + +# Run a command inside an LXC container +# +# usage: ynh_lxc_run_inside --name=name --command=command +# | arg: -n, --name= - name of the LXC +# | arg: -c, --command= - command to execute +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_run_inside() { + # Declare an array to define the options of this helper. + local legacy_args=nc + local -A args_array=([n]=name= [c]=command=) + local name + local command + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + lxc exec $name -- /bin/bash -c "$command" +} + +# Check an LXC container can start +# +# usage: ynh_lxc_check_container_start --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_check_container_start() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + ynh_print_info --message="Test du conteneur $name" + ynh_lxc_start --name=$name # Démarre le conteneur + + wait_period=0 + while ! ynh_lxc_is_started --name=$name + do + wait_period=$(($wait_period+10)) + if [ $wait_period -gt 20 ];then + break + else + sleep 5 + fi + done + + ynh_lxc_is_started --name=$name +} + +# Restart a container +# +# usage: _ynh_restart_container --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +_ynh_restart_container() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + ynh_lxc_stop --name="$name" + ynh_lxc_start --name="$name" +} + +# Keep sure the LXC is started +# +# usage: _ynh_lxc_start_and_wait --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +_ynh_lxc_start_and_wait() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # Try to start the container 3 times. + ynh_lxc_start --name=$name + local max_try=3 + local i=0 + while [ $i -lt $max_try ] + do + i=$(( i +1 )) + local failstart=0 + + # Wait for container to start, we are using systemd to check this, + # for the sake of brevity. + for j in $(seq 1 10); do + if ynh_lxc_run_inside --name=$name --command="systemctl isolate multi-user.target >/dev/null 2>/dev/null"; then + break + fi + + if [ "$j" == "10" ]; then + log_debug 'Failed to start the container ... restarting ...' + failstart=1 + + _ynh_restart_container --name="$name" + fi + + sleep 1s + done + + # Wait for container to access the internet + for j in $(seq 1 10); do + if ynh_lxc_run_inside --name=$name --command="curl -s http://wikipedia.org > /dev/null 2>/dev/null"; then + break + fi + + if [ "$j" == "10" ]; then + log_debug 'Failed to access the internet ... restarting' + failstart=1 + + _ynh_restart_container --name="$name" + fi + + sleep 1s + done + + # Has started and has access to the internet + if [ $failstart -eq 0 ] + then + break + fi + + # Fail if the container failed to start + if [ $i -eq $max_try ] && [ $failstart -eq 1 ] + then + log_error "The container miserably failed to start or to connect to the internet" + lxc info --show-log $name + return 1 + fi + done + + LXC_IP=$(ynh_lxc_run_inside --name=$name --command="hostname -I | cut -d' ' -f1 | grep -E -o \"\<[0-9.]{8,}\>\"") +} + +# Create a new LXC from an image +# +# usage: ynh_lxc_create --image=image --name=name +# | arg: -i, --image= - image to create from +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_create(){ + # Declare an array to define the options of this helper. + local legacy_args=in + local -A args_array=([i]=image= [n]=name=) + local image + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + log_info "Launching new LXC $name ..." + # Check if we can launch container from YunoHost remote image + if ynh_exec_as $app lxc remote list | grep -q "yunohost" && ynh_exec_as $app lxc image list yunohost:$image | grep -q -w $image; then + ynh_exec_as $app lxc launch yunohost:$image $name \ + -c security.nesting=true \ + -c security.privileged=true \ + -c limits.memory=80% \ + -c limits.cpu.allowance=80% | tee -a /proc/self/fd/3 + # Check if we can launch container from a local image + elif ynh_exec_as $app lxc image list $image | grep -q -w $image; then + ynh_exec_as $app lxc launch $image $name \ + -c security.nesting=true \ + -c security.privileged=true \ + -c limits.memory=80% \ + -c limits.cpu.allowance=80% | tee -a /proc/self/fd/3 + else + log_critical "Can't find base image $image" + fi + + if [ ! -z "$PACKAGE_CHECK_EXEC" ] + then + pipestatus="${PIPESTATUS[0]}" + location=$(ynh_exec_as $app lxc list --format json | jq -e --arg name $name '.[] | select(.name==$name) | .location' | tr -d '"') + [[ "$location" != "none" ]] && log_info "... on $location" + + [[ "$pipestatus" -eq 0 ]] || exit 1 + fi + + _ynh_lxc_start_and_wait --name="$name" + if [ ! -z "$PACKAGE_CHECK_EXEC" ] + then + ynh_lxc_set_witness --name="$name" + fi + ynh_lxc_create_snapshot --name="$name" --snapname="snap0" +} + +# Delete a lxc container +# +# usage: ynh_lxc_delete --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_delete() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_exists --name=$name + then + lxc delete $name --force + else + return 1 + fi +} + +# Clean the swapfiles of an LXC container +# +# usage: ynh_lxc_clean_swapfiles --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_clean_swapfiles() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + _ynh_lxc_start_and_wait --name="$name" + + ynh_lxc_run_inside --name=$name --command='for swapfile in $(ls /swap_* 2>/dev/null); do swapoff $swapfile; done' + ynh_lxc_run_inside --name=$name --command='for swapfile in $(ls /swap_* 2>/dev/null); do rm -f $swapfile; done' +} + +# Check if a snapshot exist for an LXC container +# +# usage: ynh_lxc_snapshot_exists --name=name --snapname=snapname +# | arg: -n, --name= - name of the LXC +# | arg: -s, --snapname= - name of the snapshot +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_snapshot_exists() { + # Declare an array to define the options of this helper. + local legacy_args=ns + local -A args_array=([n]=name= [s]=snapname=) + local name + local snapname + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # If the container exists + if ynh_lxc_exists --name=$name + then + if lxc list --format json | jq -e --arg name $name --arg snapname $snapname '.[] | select(.name==$name) | .snapshots' >/dev/null + then + if lxc list --format json | jq -e --arg name $name --arg snapname $snapname '.[] | select(.name==$name) | .snapshots[] | select(.name==$snapname)' >/dev/null + then + return 0 + else + return 1 + fi + else + return 1 + fi + fi +} + +# Create a snapshot of an LXC container +# +# usage: ynh_lxc_create_snapshot --name=name --snapname=snapname +# | arg: -n, --name= - name of the LXC +# | arg: -s, --snapname= - name of the snapshot +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_create_snapshot() { + # Declare an array to define the options of this helper. + local legacy_args=ns + local -A args_array=([n]=name= [s]=snapname=) + local name + local snapname + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + ynh_lxc_start_timer + + if [ ! -z "$PACKAGE_CHECK_EXEC" ] + then + # Check all the witness files, to verify if them still here + ynh_lxc_check_witness >&2 + fi + + # Remove swap files to avoid killing the CI with huge snapshots. + ynh_lxc_clean_swapfiles --name="$name" + + ynh_lxc_stop --name="$name" + + # Check if the snapshot already exist + if ! ynh_lxc_snapshot_exists --name="$name" --snapname="$snapname" + then + log_info "(Creating snapshot $snapname ...)" + lxc snapshot $name $snapname + else + log_info "(Recreating snapshot $snapname ...)" + lxc snapshot $name $snapname --reuse + fi + + _ynh_lxc_start_and_wait --name="$name" + + ynh_lxc_stop_timer 1 +} + +# Delete a snapshot of an LXC container +# +# usage: ynh_lxc_delete_snapshot --name=name --snapname=snapname +# | arg: -n, --name= - name of the LXC +# | arg: -s, --snapname= - name of the snapshot +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_delete_snapshot() { + # Declare an array to define the options of this helper. + local legacy_args=ns + local -A args_array=([n]=name= [s]=snapname=) + local name + local snapname + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_snapshot_exists --name="$name" --snapname="$snapname" + then + lxc delete $name/$snapname + return 0 + else + return 1 + fi +} + +# Load a snapshot of an LXC container +# +# usage: ynh_lxc_load_snapshot --name=name --snapname=snapname +# | arg: -n, --name= - name of the LXC +# | arg: -s, --snapname= - name of the snapshot +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_load_snapshot() { + # Declare an array to define the options of this helper. + local legacy_args=ns + local -A args_array=([n]=name= [s]=snapname=) + local name + local snapname + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_snapshot_exists --name="$name" --snapname="$snapname" + then + log_debug "Loading snapshot $snapname ..." + + # Remove swap files before restoring the snapshot. + ynh_lxc_clean_swapfiles --name="$name" + + ynh_lxc_stop --name="$name" + + lxc restore $name $snapname + _ynh_lxc_start_and_wait --name="$name" + else + return 1 + fi +} + +# Restore an LXC container from snap0 snapshot +# +# usage: ynh_lxc_restore_from_snapshot --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_restore_from_snapshot () { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + ynh_print_info --message="\e[1m> Restauration du snapshot du conteneur $name\e[0m" + ynh_lxc_load_snapshot --name=$name --snapname=snap0 + if ynh_lxc_check_container_start --name=$name + then + ynh_print_info --message="\e[92m> Conteneur $name en état de marche.\e[0m" + return 0 + else + ynh_print_info --message="\e[91m> Conteneur $name en défaut.\e[0m" + return 1 + fi +} + +# Restore an LXC container from an archive +# +# usage: ynh_lxc_restore_from_archive --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_restore_from_archive () { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ! test -e "/var/lib/lxd/snapshots/$name/snap1.tar.gz"; then + ynh_print_info --message="Aucune archive de snapshot pour le conteneur $name" + return 1 + fi + ynh_print_info --message="\e[1m> Restauration du snapshot archivé pour le conteneur $name\e[0m" + ynh_print_info --message="Suppression du snapshot" + ynh_lxc_delete_snapshot --name=$name --snapname=snap0 + ynh_print_info --message="Décompression de l'archive" + tar -x --acls --xattrs -f /var/lib/lxd/snapshots/$name/snap0.tar.gz -C / + ynh_lxc_restore_from_snapshot --name=$name + return $? +} + +# Clone an LXC container +# +# usage: ynh_lxc_clone --source=source --destination=destination +# | arg: -s, --source= - source LXC +# | arg: -d, --destination= - destination LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_clone() { + # Declare an array to define the options of this helper. + local legacy_args=sd + local -A args_array=([s]=source= [d]=destination=) + local source + local destination + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + ynh_print_info --message="Suppression du conteneur $destination" + ynh_secure_remove --file="/var/lib/lxd/snapshots/$destination/snap0.tar.gz" + ynh_lxc_reset --name=$destination + + ynh_print_info --message="\e[1m> Clone le conteneur $source sur $destination\e[0m" + lxc copy "$source" "$destination" + + ynh_lxc_check_container_start --name=$destination + STATUS=$? + if [ $STATUS -eq 1 ]; then + ynh_print_info --message="\e[91m> Conteneur $destination en défaut.\e[0m" + else + ynh_print_info --message="\e[92m> Conteneur $destination en état de marche.\e[0m" + ynh_print_info --message= "Création d'un nouveau snapshot pour le conteneur $destination" + ynh_lxc_create_snapshot --name="$destination" --snapname="snap0" + fi + return $STATUS +} + +# usage: ynh_lxc_test --name=name - +ynh_lxc_test(){ + # Declare an array to define the options of this helper. + local legacy_args=ns + local -A args_array=([n]=name= [s]=snapname=) + local name + local snapname + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_exists --name=$name + then + ynh_print_info --message="$name exist" + else + ynh_print_info --message="$name does not exist" + fi +} + +# Reset an LXC container +# +# usage: ynh_lxc_reset --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_reset() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # If the container exists + if ynh_lxc_exists --name=$name + then + # Remove swap files before deletting the continer + ynh_lxc_clean_swapfiles --name="$name" + ynh_lxc_stop --name="$name" + local current_storage=$(lxc list $name --format json --columns b | jq '.[].expanded_devices.root.pool') + swapoff "$(lxc storage get $current_storage source)/containers/$name/rootfs/swap" 2>/dev/null + ynh_lxc_delete --name=$name + fi +} + +#================================================= +# Logging helpers +#================================================= + +readonly NORMAL=$(printf '\033[0m') +readonly BOLD=$(printf '\033[1m') +readonly faint=$(printf '\033[2m') +readonly UNDERLINE=$(printf '\033[4m') +readonly NEGATIVE=$(printf '\033[7m') +readonly RED=$(printf '\033[31m') +readonly GREEN=$(printf '\033[32m') +readonly ORANGE=$(printf '\033[33m') +readonly BLUE=$(printf '\033[34m') +readonly YELLOW=$(printf '\033[93m') +readonly WHITE=$(printf '\033[39m') + +function log_title() +{ + cat << EOF | tee -a /proc/self/fd/3 +${BOLD} + ============================================ + $1 + ============================================ +${NORMAL} +EOF +} + +function log_small_title() +{ + echo -e "\n${BOLD} > ${1}${NORMAL}\n" | tee -a /proc/self/fd/3 +} + + +function log_debug() +{ + echo "$1" | tee -a /proc/self/fd/3 +} + +function log_info() +{ + echo "${1}" | tee -a /proc/self/fd/3 +} + +function log_success() +{ + echo "${BOLD}${GREEN}Success: ${1}${NORMAL}" | tee -a /proc/self/fd/3 +} + +function log_warning() +{ + echo "${BOLD}${ORANGE}Warning: ${1}${NORMAL}" | tee -a /proc/self/fd/3 +} + +function log_error() +{ + echo "${BOLD}${RED}Error: ${1}${NORMAL}" | tee -a /proc/self/fd/3 +} + +function log_critical() +{ + echo "${BOLD}${RED}Critical: ${1}${NORMAL}" | tee -a /proc/self/fd/3 + exit 1 +} + +function log_report_test_success () { + echo -e "\n${BOLD}${GREEN}--- SUCCESS ---${NORMAL}\n" | tee -a /proc/self/fd/3 +} + +function log_report_test_warning () { + echo -e "\n${BOLD}${ORANGE}--- WARNING ---${NORMAL}\n" | tee -a /proc/self/fd/3 +} + +function log_report_test_failed () { + echo -e "\n${BOLD}${RED}--- FAIL ---${NORMAL}\n" | tee -a /proc/self/fd/3 +} + +#================================================= +# Timing helpers +#================================================= + +# Start a timer +# +# usage: ynh_lxc_start_timer +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_start_timer() { + # Set the beginning of the timer + starttime=$(date +%s) +} + +# Stop a timer +# +# usage: ynh_lxc_stop_timer +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_stop_timer() { + # Ending the timer + # $1 = Type of querying + + local finishtime=$(date +%s) + # Calculate the gap between the starting and the ending of the timer + local elapsedtime=$(echo $(( $finishtime - $starttime ))) + # Extract the number of hour + local hours=$(echo $(( $elapsedtime / 3600 ))) + local elapsedtime=$(echo $(( $elapsedtime - ( 3600 * $hours) ))) + # Minutes + local minutes=$(echo $(( $elapsedtime / 60 ))) + # And seconds + local seconds=$(echo $(( $elapsedtime - ( 60 * $minutes) ))) + + local phours="" + local pminutes="" + local pseconds="" + + # Avoid null values + [ $hours -eq 0 ] || phours="$hours hour" + [ $minutes -eq 0 ] || pminutes="$minutes minute" + [ $seconds -eq 0 ] || pseconds="$seconds second" + + # Add a 's' for plural values + [ $hours -eq 1 ] && phours="${phours}, " || test -z "$phours" || phours="${phours}s, " + [ $minutes -eq 1 ] && pminutes="${pminutes}, " || test -z "$pminutes" || pminutes="${pminutes}s, " + [ $seconds -gt 1 ] && pseconds="${pseconds}s" || pseconds="0s" + + local time="${phours}${pminutes}${pseconds} ($(date '+%T'))" + if [ $1 -eq 2 ]; then + log_info "Working time for this test: $time" + elif [ $1 -eq 3 ]; then + log_info "Global working time for all tests: $time" + else + log_debug "Working time: $time" + fi +} + +#================================================= +# PACKAGE_CHECK helpers +#================================================= + +# Start an LXC and execute a command in it, to be used for PACKAGE_CHECK_EXEC +# +# usage: ynh_lxc_exec --name=name --command=command +# | arg: -n, --name= - name of the LXC +# | arg: -c, --command= - command to execute +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_exec() { + # Declare an array to define the options of this helper. + local legacy_args=nc + local -A args_array=([n]=name= [c]=command=) + local name + local command + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + _ynh_lxc_start_and_wait --name="$name" + + ynh_lxc_start_timer + + # Execute the command given in argument in the container and log its results. + lxc exec $name --env PACKAGE_CHECK_EXEC=1 -t -- /bin/bash -c "$command" + + # Store the return code of the command + local returncode=${PIPESTATUS[0]} + + log_debug "Return code: $returncode" + + ynh_lxc_stop_timer 1 + # Return the exit code of the ssh command + return $returncode +} + +# Create a witness in an LXC container +# +# usage: ynh_lxc_create_witness --name=name --witness=witness --type=type +# | arg: -n, --name= - name of the LXC +# | arg: -w, --witness= - witness to create +# | arg: -t, --type= - type of witness, can be file or directory +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_create_witness () { + # Declare an array to define the options of this helper. + local legacy_args=nwt + local -A args_array=([n]=name= [w]=witness= [t]=type=) + local name + local witness + local type + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + [ "$type" = "file" ] && local action="touch" || local action="mkdir -p" + ynh_lxc_run_inside --name=$name --command="$action $witness" +} + +# Set witness in an LXC container +# +# usage: ynh_lxc_set_witness --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_set_witness() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # Create files to check if the remove script does not remove them accidentally + log_debug "Create witness files..." + + # Nginx conf + ynh_lxc_create_witness -name=$name --witness="/etc/nginx/conf.d/$DOMAIN.d/witnessfile.conf" --type=file + ynh_lxc_create_witness -name=$name --witness="/etc/nginx/conf.d/$SUBDOMAIN.d/witnessfile.conf" --type=file + + # /etc + ynh_lxc_create_witness -name=$name --witness="/etc/witnessfile" --type=file + + # /opt directory + ynh_lxc_create_witness -name=$name --witness="/opt/witnessdir" --type=directory + + # /var/www directory + ynh_lxc_create_witness -name=$name --witness="/var/www/witnessdir" --type=directory + + # /home/yunohost.app/ + ynh_lxc_create_witness -name=$name --witness="/home/yunohost.app/witnessdir" --type=directory + + # /var/log + ynh_lxc_create_witness -name=$name --witness="/var/log/witnessfile" --type=file + + # Config fpm + ynh_lxc_create_witness -name=$name --witness="/etc/php/$DEFAULT_PHP_VERSION/fpm/pool.d/witnessfile.conf" --type=file + + # Config logrotate + ynh_lxc_create_witness -name=$name --witness="/etc/logrotate.d/witnessfile" --type=file + + # Config systemd + ynh_lxc_create_witness -name=$name --witness="/etc/systemd/system/witnessfile.service" --type=file + + # Database + ynh_lxc_run_inside --name=$name --command="mysqladmin --wait status > /dev/null 2>&1" + ynh_lxc_run_inside --name=$name --command="echo \"CREATE DATABASE witnessdb\" | mysql --wait > /dev/null 2>&1" +} + +# Check if a witness exists in an LXC container +# +# usage: ynh_lxc_create_witness --name=name --witness=witness +# | arg: -n, --name= - name of the LXC +# | arg: -w, --witness= - witness to create +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_check_witness_exist () { + # Declare an array to define the options of this helper. + local legacy_args=nw + local -A args_array=([n]=name= [w]=witness=) + local name + local witness + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + if ynh_lxc_run_inside --name=$name --command="test ! -e \"$witness\"" + then + log_error "The file $witness is missing ! Something gone wrong !" + SET_RESULT "failure" witness + fi +} + +# Check witness in an LXC container +# +# usage: ynh_lxc_check_witness --name=name +# | arg: -n, --name= - name of the LXC +# +# Requires YunoHost version *.*.* or higher. +ynh_lxc_check_witness() { + # Declare an array to define the options of this helper. + local legacy_args=n + local -A args_array=([n]=name=) + local name + # Manage arguments with getopts + ynh_handle_getopts_args "$@" + + # Check all the witness files, to verify if them still here + + # Nginx conf + ynh_lxc_check_witness_exist --name=$name --witness="/etc/nginx/conf.d/$DOMAIN.d/witnessfile.conf" + ynh_lxc_check_witness_exist --name=$name --witness="/etc/nginx/conf.d/$SUBDOMAIN.d/witnessfile.conf" + + # /etc + ynh_lxc_check_witness_exist --name=$name --witness="/etc/witnessfile" + + # /opt directory + ynh_lxc_check_witness_exist --name=$name --witness="/opt/witnessdir" + + # /var/www directory + ynh_lxc_check_witness_exist --name=$name --witness="/var/www/witnessdir" + + # /home/yunohost.app/ + ynh_lxc_check_witness_exist --name=$name --witness="/home/yunohost.app/witnessdir" + + # /var/log + ynh_lxc_check_witness_exist --name=$name --witness="/var/log/witnessfile" + + # Config fpm + ynh_lxc_check_witness_exist --name=$name --witness="/etc/php/$DEFAULT_PHP_VERSION/fpm/pool.d/witnessfile.conf" + + # Config logrotate + ynh_lxc_check_witness_exist --name=$name --witness="/etc/logrotate.d/witnessfile" + + # Config systemd + ynh_lxc_check_witness_exist --name=$name --witness="/etc/systemd/system/witnessfile.service" + + # Database + if ! ynh_lxc_run_inside --name=$name --command="mysqlshow witnessdb > /dev/null 2>&1" + then + log_error "The database witnessdb is missing ! Something gone wrong !" + SET_RESULT "failure" witness + return 1 + fi +}