From 73ceea6ad2af00f251a5e79a0a258f9fee97d531 Mon Sep 17 00:00:00 2001 From: Wayne Davison Date: Mon, 20 Dec 2021 17:28:18 -0800 Subject: [PATCH] Convert atomic-rsync to python. --- support/atomic-rsync | 179 ++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 88 deletions(-) diff --git a/support/atomic-rsync b/support/atomic-rsync index 0346fb49..37363e43 100755 --- a/support/atomic-rsync +++ b/support/atomic-rsync @@ -1,92 +1,83 @@ -#!/usr/bin/env perl -# +#!/usr/bin/env python3 # This script lets you update a hierarchy of files in an atomic way by # first creating a new hierarchy using rsync's --link-dest option, and # then swapping the hierarchy into place. **See the usage message for # more details and some important caveats!** -use strict; -use warnings; -use Cwd 'abs_path'; - -my $RSYNC_PROG = '/usr/bin/rsync'; -my $RM_PROG = '/bin/rm'; - -my $dest_dir = $ARGV[-1]; -&usage if !defined $dest_dir || $dest_dir =~ /(^-|^$)/ || grep(/^--help/, @ARGV); -$dest_dir =~ s{(?<=.)/+$} {}; - -if (!-d $dest_dir) { - die "$dest_dir is not a directory.\nUse --help for help.\n"; -} - -if (@_ = grep(/^--[a-z]+-dest\b/, @ARGV)) { - $_ = join(' or ', @_); - die "You cannot use the $_ option with atomic-rsync.\nUse --help for help.\n"; -} - -my $symlink_content = readlink $dest_dir; # undef when a real dir - -my $dest_arg = $dest_dir; -# This gives us the real destination dir, with all symlinks dereferenced. -$dest_dir = abs_path($dest_dir); -if ($dest_dir eq '/') { - die qq|You must not use "/" as the destination directory.\nUse --help for help.\n|; -} - -my($old_dir, $new_dir); -if (defined $symlink_content && $dest_dir =~ /-([12])$/) { - my $num = 3 - $1; - $old_dir = undef; - ($new_dir = $dest_dir) =~ s/-[12]$/-$num/; - $symlink_content =~ s/-[12]$/-$num/; -} else { - $old_dir = "$dest_dir~old~"; - $new_dir = "$dest_dir~new~"; -} - -$ARGV[-1] = "$new_dir/"; - -system($RM_PROG, '-rf', $old_dir) if defined $old_dir && -d $old_dir; -system($RM_PROG, '-rf', $new_dir) if -d $new_dir; - -if (system($RSYNC_PROG, "--link-dest=$dest_dir", @ARGV)) { - if ($? == -1) { - print "failed to execute $RSYNC_PROG: $!\n"; - } elsif ($? & 127) { - printf "child died with signal %d, %s coredump\n", - ($? & 127), ($? & 128) ? 'with' : 'without'; - } else { - printf "child exited with value %d\n", $? >> 8; - } - exit 1; -} - -if (!defined $old_dir) { - atomic_symlink($symlink_content, $dest_arg); - exit; -} - -rename($dest_dir, $old_dir) or die "Unable to rename $dest_dir to $old_dir: $!"; -rename($new_dir, $dest_dir) or die "Unable to rename $new_dir to $dest_dir: $!"; - -exit; - -sub atomic_symlink -{ - my($target, $link) = @_; - my $newlink = "$link~new~"; - - unlink($newlink); # Just in case - symlink($target, $newlink) or die "Unable to symlink $newlink -> $target: $!\n"; - rename($newlink, $link) or die "Unable to rename $newlink to $link: $!\n"; -} - - -sub usage -{ - die <