From f663f69f2771c9b3bc7c22d8068ce548e934b236 Mon Sep 17 00:00:00 2001 From: Maniack Crudelis Date: Wed, 10 May 2017 22:47:23 +0200 Subject: [PATCH] Snapshots instead of multiple installations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usage de snapshot pour les installations de base. Réduit la durée des tests en évitant de réinstaller l'application plusieurs fois avec les mêmes paramètres. --- package_check.sh | 19 ++++--- sub_scripts/launcher.sh | 67 ++++++++++++++++++++--- sub_scripts/testing_process.sh | 97 +++++++++++++++++++++------------- 3 files changed, 132 insertions(+), 51 deletions(-) diff --git a/package_check.sh b/package_check.sh index 2d5e761..3025909 100755 --- a/package_check.sh +++ b/package_check.sh @@ -929,14 +929,14 @@ then public_private_arg=$(echo "$line" | grep -o "|private=[[:alnum:]]*" | cut -d "=" -f2) fi -if echo "$LIGNE" | grep -q "(PATH)"; then # Path dans le manifest - MANIFEST_PATH=$(echo "$LIGNE" | cut -d '=' -f1) # Récupère la clé du manifest correspondant au path - parse_path=$(echo "$LIGNE" | cut -d '"' -f2) # Lit le path du check_process - if [ -n "$parse_path" ]; then # Si le path n'est pas null, utilise ce path au lieu de la valeur par défaut. - PATH_TEST=$(echo "$LIGNE" | cut -d '"' -f2) - fi - LIGNE=$(echo "$LIGNE" | cut -d '(' -f1) # Retire l'indicateur de clé de manifest à la fin de la ligne -fi + if echo "$LIGNE" | grep -q "(PATH)"; then # Path dans le manifest + MANIFEST_PATH=$(echo "$LIGNE" | cut -d '=' -f1) # Récupère la clé du manifest correspondant au path + parse_path=$(echo "$LIGNE" | cut -d '"' -f2) # Lit le path du check_process + if [ -n "$parse_path" ]; then # Si le path n'est pas null, utilise ce path au lieu de la valeur par défaut. + PATH_TEST=$(echo "$LIGNE" | cut -d '"' -f2) + fi + LIGNE=$(echo "$LIGNE" | cut -d '(' -f1) # Retire l'indicateur de clé de manifest à la fin de la ligne + fi # Parse all tests to perform # Extract the checks options section from the second partial file @@ -1003,6 +1003,9 @@ fi # Print the final results of the tests TEST_RESULTS + # Destroy all snapshots other than snap0 + destroy_temporary_snapshot + done <<< "$(grep "^;; " "$check_process")" # No check_process file. Try to parse the manifest. diff --git a/sub_scripts/launcher.sh b/sub_scripts/launcher.sh index 9885d9a..766e86b 100755 --- a/sub_scripts/launcher.sh +++ b/sub_scripts/launcher.sh @@ -7,6 +7,7 @@ echo -e "Loads functions from launcher.sh" #================================================= arg_ssh="-tt" +snapshot_path="/var/lib/lxcsnaps/$lxc_name" #================================================= @@ -14,6 +15,57 @@ is_lxc_running () { sudo lxc-info --name=$lxc_name | grep --quiet "RUNNING" } +create_temp_backup () { + # Create a temporary snapshot + + # Check all the witness files, to verify if them still here + check_witness_files + + # Stop the container, before its snapshot + sudo lxc-stop --name $lxc_name + + # Create the snapshot. + sudo lxc-snapshot --name $lxc_name >> "$test_result" 2>&1 + + # Get the last created snapshot and return it + echo "$(sudo lxc-snapshot --name $lxc_name --list | head --lines=1 | cut --delimiter=' ' --fields=1)" + + # Restart the container, after the snapshot + LXC_START "true" >&2 +} + +use_temp_snapshot () { + # Use a temporary snapshot, if it already exists + # $1 = Name of the snapshot to use + local snapshot_name=$1 + + # Restore this snapshot. + sudo rsync --acls --archive --delete --executability --itemize-changes --xattrs "$snapshot_path/$snapshot_name/rootfs/" "/var/lib/lxc/$lxc_name/rootfs/" > /dev/null 2>> "$test_result" + + # Fake the yunohost_result return code of the installation + yunohost_result=0 +} + +destroy_temporary_snapshot () { + # Destroy all snapshots other than snap0 + + while true + do + local snapshot=$(sudo lxc-snapshot --name $lxc_name --list | head --lines=1 | cut --delimiter=' ' --fields=1) + if [ -n "$snapshot" ] && [ "$snapshot" != "snap0" ] + then + echo "Destroy temporary snapshot $snapshot." + sudo lxc-snapshot --name $lxc_name --destroy $snapshot + else + break + fi + done + + # Clear the variables which contains the snapshot names + unset root_snapshot + unset subpath_snapshot +} + LXC_INIT () { # Initialize LXC network @@ -119,8 +171,6 @@ LXC_START () { LXC_STOP () { # Stop and restore the LXC container - local snapshot_path="/var/lib/lxcsnaps/$lxc_name/snap0" - # Stop the LXC container if is_lxc_running; then echo "Stop the LXC container" | tee --append "$test_result" @@ -129,22 +179,22 @@ LXC_STOP () { # Fix the missing hostname in the hosts file # If the hostname is missing in /etc/hosts inside the snapshot - if ! sudo grep --quiet "$lxc_name" "$snapshot_path/rootfs/etc/hosts" + if ! sudo grep --quiet "$lxc_name" "$snapshot_path/snap0/rootfs/etc/hosts" then # If the hostname was replaced by snap0, fix it - if sudo grep --quiet "snap0" "$snapshot_path/rootfs/etc/hosts" + if sudo grep --quiet "snap0" "$snapshot_path/snap0/rootfs/etc/hosts" then # Replace snap0 by the real hostname - sudo sed --in-place "s/snap0/$lxc_name/" "$snapshot_path/rootfs/etc/hosts" + sudo sed --in-place "s/snap0/$lxc_name/" "$snapshot_path/snap0/rootfs/etc/hosts" else # Otherwise, simply add the hostname - echo "127.0.0.1 $lxc_name" | sudo tee --append "$snapshot_path/rootfs/etc/hosts" > /dev/null + echo "127.0.0.1 $lxc_name" | sudo tee --append "$snapshot_path/snap0/rootfs/etc/hosts" > /dev/null fi fi # Restore the snapshot. echo "Restore the previous snapshot." | tee --append "$test_result" - sudo rsync --acls --archive --delete --executability --itemize-changes --xattrs "$snapshot_path/rootfs/" "/var/lib/lxc/$lxc_name/rootfs/" > /dev/null 2>> "$test_result" + sudo rsync --acls --archive --delete --executability --itemize-changes --xattrs "$snapshot_path/snap0/rootfs/" "/var/lib/lxc/$lxc_name/rootfs/" > /dev/null 2>> "$test_result" } LXC_TURNOFF () { @@ -169,6 +219,9 @@ LXC_TURNOFF () { then sudo ifdown --force $lxc_bridge | tee --append "$test_result" 2>&1 fi + + # Destroy all snapshots other than snap0 + destroy_temporary_snapshot } LXC_CONNECT_INFO () { diff --git a/sub_scripts/testing_process.sh b/sub_scripts/testing_process.sh index 7cea6bb..e8ca1a1 100644 --- a/sub_scripts/testing_process.sh +++ b/sub_scripts/testing_process.sh @@ -46,6 +46,47 @@ SETUP_APP () { # 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 +} + +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 + # Then create a snapshot + ECHO_FORMAT "Create a snapshot for root installation.\n" "white" clog + root_snapshot=$(create_temp_backup) + 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 + # Then create a snapshot + ECHO_FORMAT "Create a snapshot for sub path installation.\n" "white" clog + subpath_snapshot=$(create_temp_backup) + 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 () { @@ -96,7 +137,7 @@ CHECK_URL () { # 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 $check_domain #package_check" | sudo tee --append /etc/hosts > /dev/null + 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 @@ -378,10 +419,7 @@ CHECK_SETUP () { replace_manifest_key "public" "$public_public_arg" # Install the application in a LXC container - SETUP_APP - - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR + STANDARD_SETUP_APP # Try to access the app by its url CHECK_URL @@ -457,10 +495,7 @@ CHECK_UPGRADE () { # Install the application in a LXC container ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog - SETUP_APP - - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR + STANDARD_SETUP_APP # Check if the install had work if [ $yunohost_result -ne 0 ] @@ -580,9 +615,6 @@ CHECK_PUBLIC_PRIVATE () { # Install the application in a LXC container SETUP_APP - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR - # Try to access the app by its url CHECK_URL @@ -681,9 +713,6 @@ CHECK_MULTI_INSTANCE () { # Install the application in a LXC container SETUP_APP - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR - # Store the result in the correct variable # First installation if [ $i -eq 1 ] @@ -822,9 +851,6 @@ CHECK_COMMON_ERROR () { # Install the application in a LXC container SETUP_APP - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR - # Try to access the app by its url CHECK_URL @@ -905,10 +931,7 @@ CHECK_BACKUP_RESTORE () { fi # Install the application in a LXC container - SETUP_APP - - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR + STANDARD_SETUP_APP # BACKUP # Made a backup if the installation succeed @@ -1108,22 +1131,29 @@ CHECK_CHANGE_URL () { # Install the application in a LXC container ECHO_FORMAT "\nPreliminary install...\n" "white" "bold" clog - SETUP_APP + STANDARD_SETUP_APP - # Analyse the log to extract "warning" and "error" lines - LOG_EXTRACTOR +# Wait for next release... +LXC_START "yunohost app --help | grep --quiet change-url" +if [ $? -ne 0 ] +then + ECHO_FORMAT "change-url is only available on testing or unstable...\n" "red" "bold" + RESULT_change_url=0 + return 0 +fi +# ... # Check if the install had work if [ $yunohost_result -ne 0 ] then - ECHO_FORMAT "\nInstallation failed...\n" "red" "bold" + ECHO_FORMAT "Installation failed...\n" "red" "bold" else - ECHO_FORMAT "\nChange the url from $sub_domain$check_path to $new_domain$new_path...\n" "white" "bold" clog + 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 yunohost --debug app change-url $ynh_app_id -d \"$new_domain\" -p \"$new_path\"" - # yunohost_result gets the return code of the upgrade + # yunohost_result gets the return code of the change-url script yunohost_result=$? # Print the result of the change_url command @@ -1207,7 +1237,7 @@ TEST_LAUNCHER () { set_witness_files () { # Create files to check if the remove script does not remove them accidentally - echo -n "Create witness files" | tee --append "$test_result" + echo "Create witness files..." | tee --append "$test_result" lxc_dir="/var/lib/lxc/$lxc_name/rootfs" @@ -1245,13 +1275,8 @@ set_witness_files () { create_witness_file "/etc/systemd/system/witnessfile.service" file # Database - for timeout in `seq 1 10` - do - 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 && break - echo -n "." - sleep 1 - done - echo "" + 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 () {