Subversion Repositories zfs_utils

Rev

Rev 30 | Rev 33 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 30 Rev 31
Line 8... Line 8...
8
use Data::Dumper;
8
use Data::Dumper;
9
use ZFS_Utils qw(loadConfig shredFile logMsg makeReplicateCommands mountDriveByLabel mountGeli runCmd $logFileName $displayLogsOnConsole);
9
use ZFS_Utils qw(loadConfig shredFile logMsg makeReplicateCommands mountDriveByLabel mountGeli runCmd $logFileName $displayLogsOnConsole);
10
 
10
 
11
# set the log file to be next to this script
11
# set the log file to be next to this script
12
$logFileName = "$FindBin::Bin/sneakernet.log";
12
$logFileName = "$FindBin::Bin/sneakernet.log";
-
 
13
# log only for one run
-
 
14
unlink ( $logFileName ) if -f $logFileName;
-
 
15
 
13
# display all log messages on console in addition to the log file
16
# display all log messages on console in addition to the log file
14
$displayLogsOnConsole = 1;
17
$displayLogsOnConsole = 1;
15
 
18
 
16
my $configFileName = "$0.conf.yaml";
19
my $configFileName = "$0.conf.yaml";
17
 
20
 
Line 105... Line 108...
105
      logMsg("Error: could not write status file '$filename': $!");
108
      logMsg("Error: could not write status file '$filename': $!");
106
      die;
109
      die;
107
   }
110
   }
108
}
111
}
109
 
112
 
-
 
113
# simple sub to take root/dataset/datset/dataset and turn it into
-
 
114
# dataset.dataset.dataset
-
 
115
sub replaceSlashWithDot {
-
 
116
   my $string = shift;
-
 
117
   my @parts = split( "/", $string );
-
 
118
   shift @parts;
-
 
119
   return join( '.', @parts );
-
 
120
}
-
 
121
 
110
# perform replication on source server
122
# perform replication on source server
111
# $config - configuration hashref
123
# $config - configuration hashref
112
# $statusList - list of last snapshots replicated for each dataset in previous replications
124
# $statusList - list of last snapshots replicated for each dataset in previous replications
113
# return new status list after replication containing updated last snapshots
125
# return new status list after replication containing updated last snapshots
114
# this script will actually replicate the datasets to the sneakernet disk
126
# this script will actually replicate the datasets to the sneakernet disk
115
sub doSourceReplication {
127
sub doSourceReplication {
116
   my ($config, $statusList) = @_;
128
   my ($config, $statusList) = @_;
117
   my $newStatus = [];
129
   my $newStatus = [];
118
   foreach my $dataset ( sort keys %{$config->{datasets}} ) {
130
   foreach my $dataset ( sort keys %{$config->{datasets}} ) {
119
      logMsg("Processing dataset '$dataset'\n");
131
      logMsg("Processing dataset '$dataset'");
-
 
132
      # get list of all snapshots on dataset
120
      my $sourceList = [ runCmd( "zfs", "list", "-rt", "snap", "-H", "-o", "name", $config->{datasets}->{$dataset}->{source} ) ];
133
      my $sourceList = [ runCmd( "zfs", "list", "-rt", "snap", "-H", "-o", "name", $config->{datasets}->{$dataset}->{source} ) ];
121
      
-
 
122
      # process dataset here
134
      # process dataset here
123
      my $commands = makeReplicateCommands($sourceList, $statusList, $newStatus );
135
      my $commands = makeReplicateCommands($sourceList, $statusList, $newStatus );
-
 
136
      if ( %$commands ) {
124
      foreach my $cmd ( @$commands ) {
137
         foreach my $cmd ( keys %$commands ) {
-
 
138
            my $command = $commands->{$cmd};
-
 
139
            $command .= " | openssl enc -aes-256-cbc -K $config->{transport}->{encryption}->{key} -iv $config->{transport}->{encryption}->{IV} " if $config->{transport}->{encryption}->{key};
-
 
140
            $command .= " > $config->{transport}->{mount_point}/" . replaceSlashWithDot($cmd);
125
         logMsg("Running command: $cmd\n");
141
            logMsg("Running command: $command");
126
         #runCmd( split( /\s+/, $cmd ) );
142
            #runCmd( split( /\s+/, $cmd ) );
-
 
143
         }
-
 
144
      } else {
-
 
145
         logMsg( "Nothing to do for $dataset" ); 
127
      }
146
      }
128
   }
147
   }
129
   return $newStatus;
148
   return $newStatus;
130
}
149
}
131
 
150
 
-
 
151
# how to handle a fatal error
-
 
152
sub fatalError {
-
 
153
   my $message = shift;
-
 
154
   logMsg( $message );
-
 
155
   die;
-
 
156
}
-
 
157
 
132
 
158
 
133
##################### main program starts here #####################
159
##################### main program starts here #####################
134
# Example to create a random key for encryption/decryption:
160
# Example to create a random key for encryption/decryption:
135
# generate a random key with
161
# generate a random key with
136
# openssl rand 32 | xxd -p | tr -d '\n' > test.key
162
# openssl rand 32 | xxd -p | tr -d '\n' > test.key
Line 140... Line 166...
140
 
166
 
141
# set some defaults
167
# set some defaults
142
$config->{'status_file'} = "$0.status" unless ( defined $config->{'status_file'} );
168
$config->{'status_file'} = "$0.status" unless ( defined $config->{'status_file'} );
143
 
169
 
144
 
170
 
145
die "Invalid config file: missing source and/or target server\n"
171
fatalError( "Invalid config file: missing source and/or target server" )
146
    unless (defined $config->{source_server} && defined $config->{target_server});
172
    unless (defined $config->{source_server} && defined $config->{target_server});
147
 
173
 
-
 
174
# mount the transport drive, fatal error if we can not find it
-
 
175
fatalError( "Unable to mount tranport drive with label $config->{transport}->{disk_label}" )
-
 
176
   unless $config->{transport}->{mount_point} =  mountDriveByLabel( $config->{transport}->{disk_label}, $config->{transport}->{mount_point}, $config->{transport}->{timeout} );
-
 
177
 
148
my $servername = `hostname -s`;
178
my $servername = `hostname -s`;
149
chomp $servername;
179
chomp $servername;
150
if ( $servername eq $config->{source_server}->{hostname} ) {
180
if ( $servername eq $config->{source_server}->{hostname} ) {
151
    logMsg "Running as source server\n";
181
    logMsg "Running as source server\n";
152
    my $statusList = getStatusFile($config->{status_file});
182
    my $statusList = getStatusFile($config->{status_file});
Line 160... Line 190...
160
} else {
190
} else {
161
    logMsg "This server ($servername) is neither source nor target server as per config\n";
191
    logMsg "This server ($servername) is neither source nor target server as per config\n";
162
    die;
192
    die;
163
}
193
}
164
 
194
 
-
 
195
# unmount the sneakernet drive
-
 
196
`umount $config->{transport}->{mount_point}`;
-
 
197
# and remove the directory
-
 
198
unlink $config->{transport}->{mount_point};
-
 
199
 
165
die "Source and target server logic not yet implemented\n";
200
die "Source and target server logic not yet implemented\n";
166
 
201
 
167
#my $newStatus = [];
202
#my $newStatus = [];
168
#foreach my $dataset ( sort keys %{$config->{datasets}} ) {
203
#foreach my $dataset ( sort keys %{$config->{datasets}} ) {
169
#   logMsg("Processing dataset '$dataset'");
204
#   logMsg("Processing dataset '$dataset'");