Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2018-09-10 09:24:34 +0200
committerErich Eckner <git@eckner.net>2018-09-10 09:24:34 +0200
commit6d10a24d55bfdadcce69f3f0beb4c1a018af8060 (patch)
tree30e2c60375f9ae6590b2b440f67c1a61229bf686 /lib
parent1c608353d51ad59d9fafbc71067c988ce7a584d1 (diff)
lib/common-functions: failsafe_sftp() new
Diffstat (limited to 'lib')
-rwxr-xr-xlib/common-functions62
1 files changed, 61 insertions, 1 deletions
diff --git a/lib/common-functions b/lib/common-functions
index 319a85e..6e0892d 100755
--- a/lib/common-functions
+++ b/lib/common-functions
@@ -260,7 +260,7 @@ remove_old_package_versions() {
s|^|rm "|
s|$|"|
' "${tmp_dir}/sftp-removes" | \
- ${master_mirror_sftp_command}
+ failsafe_sftp
fi
)
@@ -822,3 +822,63 @@ recompress_gz() {
done
rm "${tmp_file}"
}
+
+# failsafe_sftp
+# execute the commands from stdin on the master mirror, retrying if
+# unsuccessful
+# caveats:
+# - only checks for success of "rm", "ln", "rename"
+# - commands must be executable in arbitrary order
+failsafe_sftp() {
+ ( # new shell is intentional
+ temp_dir=$(mktemp -d "tmp.common-functions.sftp_failsave.XXXXXXXXXX")
+ trial_counter=20
+ trap 'rm -rf --one-file-system "${temp_dir}"' EXIT
+ cat > "${temp_dir}/input"
+ sed -n '
+ s/^rm "\([^"]\+\)"$/- \1/
+ s/^ln\( [^"]\S*\)* "\([^"]\+\)" "[^"]\+"$/+ \2/
+ s/^rename "\([^"]\+\)" "\([^"]\+\)"$/- \1\n+ \2/
+ T
+ p
+ ' "${temp_dir}/input" > \
+ "${temp_dir}/expectations"
+ if ${master_mirror_sftp_command} < "${temp_dir}/input"; then
+ # we're done
+ exit 0
+ fi
+ # make failing sftp commands non-fatal - maybe some succeeded above?
+ sed -i '
+ s/^[^-]/-\0/
+ ' "${temp_dir}/input"
+ # we stop on exhausted $trial_counter
+ while [ ${trial_counter} -gt 0 ]; do
+ wait_some_time 30
+ # success requires 3 things:
+ # - succeeding sftp executions (commands are non-critical already)
+ # - succeeding sftp command to create listing (e.g. all expected
+ # files are found)
+ # - no unexpected files were found
+ if ${master_mirror_sftp_command} < \
+ "${temp_dir}/input" && \
+ sed '
+ s/^+ \(\S\+\)$/ls -1 "\1"/
+ s,^- \(\S\+/\)[^/]\+$,ls -1 "\1",
+ ' "${temp_dir}/expectations" | \
+ sort -u | \
+ ${master_mirror_sftp_command} > "${temp_dir}/check" && \
+ ! grep -qxF "$(
+ sed -n '
+ s/^- //
+ T
+ p
+ ' "${temp_dir}/expectations"
+ )" "${temp_dir}/check"; then
+ exit 0
+ fi
+ trial_counter=$((trial_counter-1))
+ done
+ exit 1
+ ) || \
+ return $?
+}