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.
This commit is contained in:
Tim Byrne 2020-01-16 16:27:59 -06:00
parent 3e42bd9f52
commit 04b98a96cb
No known key found for this signature in database
GPG Key ID: 14DB4FC2465A4B12
1 changed files with 12 additions and 6 deletions

18
yadm
View File

@ -304,6 +304,7 @@ function choose_template_cmd() {
function template_default() { function template_default() {
input="$1" input="$1"
output="$2" output="$2"
temp_file="${output}.$$.$RANDOM"
# the explicit "space + tab" character class used below is used because not # the explicit "space + tab" character class used below is used because not
# all versions of awk seem to support the POSIX character classes [[:blank:]] # all versions of awk seem to support the POSIX character classes [[:blank:]]
@ -362,12 +363,14 @@ EOF
-v distro="$local_distro" \ -v distro="$local_distro" \
-v source="$input" \ -v source="$input" \
"$awk_pgm" \ "$awk_pgm" \
"$input" > "$output" "$input" > "$temp_file"
[ -f "$temp_file" ] && mv -f "$temp_file" "$output"
} }
function template_j2cli() { function template_j2cli() {
input="$1" input="$1"
output="$2" output="$2"
temp_file="${output}.$$.$RANDOM"
YADM_CLASS="$local_class" \ YADM_CLASS="$local_class" \
YADM_OS="$local_system" \ YADM_OS="$local_system" \
@ -375,12 +378,14 @@ function template_j2cli() {
YADM_USER="$local_user" \ YADM_USER="$local_user" \
YADM_DISTRO="$local_distro" \ YADM_DISTRO="$local_distro" \
YADM_SOURCE="$input" \ 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() { function template_envtpl() {
input="$1" input="$1"
output="$2" output="$2"
temp_file="${output}.$$.$RANDOM"
YADM_CLASS="$local_class" \ YADM_CLASS="$local_class" \
YADM_OS="$local_system" \ YADM_OS="$local_system" \
@ -388,7 +393,8 @@ function template_envtpl() {
YADM_USER="$local_user" \ YADM_USER="$local_user" \
YADM_DISTRO="$local_distro" \ YADM_DISTRO="$local_distro" \
YADM_SOURCE="$input" \ 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 ****** # ****** yadm Commands ******
@ -629,7 +635,6 @@ function alt_past_linking() {
# loop over all "tracked" files # loop over all "tracked" files
# for every file which is a *##yadm.j2 create a real file # for every file which is a *##yadm.j2 create a real file
local temp="$(mktemp)"
local match="^(.+)##yadm\\.j2$" local match="^(.+)##yadm\\.j2$"
for tracked_file in "${tracked_files[@]}" "${ENCRYPT_INCLUDE_FILES[@]}"; do for tracked_file in "${tracked_files[@]}" "${ENCRYPT_INCLUDE_FILES[@]}"; do
tracked_file="$YADM_WORK/$tracked_file" tracked_file="$YADM_WORK/$tracked_file"
@ -639,13 +644,14 @@ function alt_past_linking() {
if envtpl_available; then if envtpl_available; then
debug "Creating $real_file from template $tracked_file" debug "Creating $real_file from template $tracked_file"
[ -n "$loud" ] && echo "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_CLASS="$local_class" \
YADM_OS="$local_system" \ YADM_OS="$local_system" \
YADM_HOSTNAME="$local_host" \ YADM_HOSTNAME="$local_host" \
YADM_USER="$local_user" \ YADM_USER="$local_user" \
YADM_DISTRO="$local_distro" \ YADM_DISTRO="$local_distro" \
"$ENVTPL_PROGRAM" --keep-template "$tracked_file" -o "$temp" "$ENVTPL_PROGRAM" --keep-template "$tracked_file" -o "$temp_file"
mv "$temp" "$real_file" [ -f "$temp_file" ] && mv -f "$temp_file" "$real_file"
else else
debug "envtpl not available, not creating $real_file from template $tracked_file" 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" [ -n "$loud" ] && echo "envtpl not available, not creating $real_file from template $tracked_file"