From 04b98a96cbd300dcb7c0a458ebc752d19013ebbf Mon Sep 17 00:00:00 2001 From: Tim Byrne Date: Thu, 16 Jan 2020 16:27:59 -0600 Subject: [PATCH] Ensure all templates are written atomically This takes jonasc's change, and applies it to all template writing. Also removes the dependency on mktemp, and only moves files if they are successfully written. --- yadm | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/yadm b/yadm index 22b9353..c8e31da 100755 --- a/yadm +++ b/yadm @@ -304,6 +304,7 @@ function choose_template_cmd() { function template_default() { input="$1" output="$2" + temp_file="${output}.$$.$RANDOM" # the explicit "space + tab" character class used below is used because not # all versions of awk seem to support the POSIX character classes [[:blank:]] @@ -362,12 +363,14 @@ EOF -v distro="$local_distro" \ -v source="$input" \ "$awk_pgm" \ - "$input" > "$output" + "$input" > "$temp_file" + [ -f "$temp_file" ] && mv -f "$temp_file" "$output" } function template_j2cli() { input="$1" output="$2" + temp_file="${output}.$$.$RANDOM" YADM_CLASS="$local_class" \ YADM_OS="$local_system" \ @@ -375,12 +378,14 @@ function template_j2cli() { YADM_USER="$local_user" \ YADM_DISTRO="$local_distro" \ YADM_SOURCE="$input" \ - "$J2CLI_PROGRAM" "$input" -o "$output" + "$J2CLI_PROGRAM" "$input" -o "$temp_file" + [ -f "$temp_file" ] && mv -f "$temp_file" "$output" } function template_envtpl() { input="$1" output="$2" + temp_file="${output}.$$.$RANDOM" YADM_CLASS="$local_class" \ YADM_OS="$local_system" \ @@ -388,7 +393,8 @@ function template_envtpl() { YADM_USER="$local_user" \ YADM_DISTRO="$local_distro" \ YADM_SOURCE="$input" \ - "$ENVTPL_PROGRAM" --keep-template "$input" -o "$output" + "$ENVTPL_PROGRAM" --keep-template "$input" -o "$temp_file" + [ -f "$temp_file" ] && mv -f "$temp_file" "$output" } # ****** yadm Commands ****** @@ -629,7 +635,6 @@ function alt_past_linking() { # loop over all "tracked" files # for every file which is a *##yadm.j2 create a real file - local temp="$(mktemp)" local match="^(.+)##yadm\\.j2$" for tracked_file in "${tracked_files[@]}" "${ENCRYPT_INCLUDE_FILES[@]}"; do tracked_file="$YADM_WORK/$tracked_file" @@ -639,13 +644,14 @@ function alt_past_linking() { if envtpl_available; then debug "Creating $real_file from template $tracked_file" [ -n "$loud" ] && echo "Creating $real_file from template $tracked_file" + temp_file="${real_file}.$$.$RANDOM" YADM_CLASS="$local_class" \ YADM_OS="$local_system" \ YADM_HOSTNAME="$local_host" \ YADM_USER="$local_user" \ YADM_DISTRO="$local_distro" \ - "$ENVTPL_PROGRAM" --keep-template "$tracked_file" -o "$temp" - mv "$temp" "$real_file" + "$ENVTPL_PROGRAM" --keep-template "$tracked_file" -o "$temp_file" + [ -f "$temp_file" ] && mv -f "$temp_file" "$real_file" else debug "envtpl not available, not creating $real_file from template $tracked_file" [ -n "$loud" ] && echo "envtpl not available, not creating $real_file from template $tracked_file"