WIP: Started work on a new Storage->copy_device() method that will do 'dd' calls.

Fixed a bug in System->update_hosts() that was causing hosts to be constantly rewritten. (Well, I hope fixed, this has been a notoriously buggy part of the program...)

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 3 years ago
parent 0fc394b294
commit 8e436ffec7
  1. 62
      Anvil/Tools/Storage.pm
  2. 58
      Anvil/Tools/System.pm
  3. 1
      tools/anvil-provision-server

@ -22,6 +22,7 @@ my $THIS_FILE = "Storage.pm";
# check_md5sums # check_md5sums
# compress # compress
# copy_file # copy_file
# copy_device
# delete_file # delete_file
# find # find
# get_file_stats # get_file_stats
@ -1263,6 +1264,67 @@ fi";
} }
=head3 copy_device
This uses the C<< dd >> system call, possibly over ssh, to create a copy of the source on the destination. Being based on C<< dd >>, this works with raw block devices and to or from files.
B<< Warning >>: This must be used carefully! Calling this backwards could destroy data!
B<< Note >>: The caller is responsible for ensuring the data on the soure will not change during the copy. If the source is a server, make sure it's off. If the source is a file system, make sure it's unmounted.
Parameters;
=head3 block_size (optional, default '4M')
This is the block size to be used for the copy. Specifically, this transtes into 'read <size> bytes, copy, read <size> bytes, copy'. This should match the size of the logical extents, block size or similar where needed. Most LVM logical extents are 4 MiB, so the default of C<< 4M >> should be fine in most cases.
B<< Note >>: See C<< man dd >> for valid formatting of this option.
=head3 calculate_sums (Optional, default '0')
If set to C<< 1 >>, the C<< md5sum >> of the source and destination are calculated and returned. If this is not used, the returned sum fields will be an empty string.
B<< Note >>: Calculating sums is highly advised, but can increase the time it takes for the copy to complete!
=head3 destination (required)
This is the full path to the destination (copy to) file or device. If the source is remote, used the format C<< <remote_user>@target:/path/to/file >>.
B<< Note >>: Only the source OR the destination can be remote, not both!
=head3 source (required)
This is the full path to the source (copy from) file or device. If the source is remote, used the format C<< <remote_user>@target:/path/to/file >>.
B<< Note >>: Only the source OR the destination can be remote, not both!
=cut
sub copy_device
{
my $self = shift;
my $parameter = shift;
my $anvil = $self->parent;
my $debug = defined $parameter->{debug} ? $parameter->{debug} : 3;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => $debug, key => "log_0125", variables => { method => "Storage->delete_file()" }});
my $file = defined $parameter->{file} ? $parameter->{file} : "";
my $password = defined $parameter->{password} ? $parameter->{password} : "";
my $port = defined $parameter->{port} ? $parameter->{port} : 22;
my $remote_user = defined $parameter->{remote_user} ? $parameter->{remote_user} : "root";
my $target = defined $parameter->{target} ? $parameter->{target} : "";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
file => $file,
password => $anvil->Log->is_secure($password),
port => $port,
remote_user => $remote_user,
target => $target,
}});
return("");
}
=head3 delete_file =head3 delete_file
This deletes a file. Pretty much what it says on the tin. When run locally, it uses C<< unlink >>. When run on a remote machine, it uses C<< rm -f >>. As such, this will not delete directories, nor will it delete recursively. This deletes a file. Pretty much what it says on the tin. When run locally, it uses C<< unlink >>. When run on a remote machine, it uses C<< rm -f >>. As such, this will not delete directories, nor will it delete recursively.

@ -4902,7 +4902,6 @@ sub update_hosts
# Read in the existing hosts file # Read in the existing hosts file
my $add_header = 1; my $add_header = 1;
my $changes = 0;
my $added_lo_ipv4 = 0; my $added_lo_ipv4 = 0;
my $added_lo_ipv6 = 0; my $added_lo_ipv6 = 0;
my $new_body = ""; my $new_body = "";
@ -4912,6 +4911,35 @@ sub update_hosts
}); });
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_body => $old_body }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_body => $old_body }});
# Look for duplicate empty lines and clear them.
my $last_line_blank = 0;
my $cleaned_body = "";
foreach my $line (split/\n/, $old_body)
{
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { line => $line }});
if ($line)
{
$last_line_blank = 0;
$cleaned_body .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { last_line_blank => $last_line_blank }});
}
elsif (not $last_line_blank)
{
$last_line_blank = 1;
$cleaned_body .= $line."\n";
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { last_line_blank => $last_line_blank }});
}
}
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { last_line_blank => $last_line_blank }});
my $difference = diff \$old_body, \$cleaned_body, { STYLE => 'Unified' };
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { difference => $difference }});
if ($difference)
{
$old_body = $cleaned_body;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { old_body => $old_body }});
}
# This will track the IPs we've seen. We'll only write these out once, and skip any futher entries # This will track the IPs we've seen. We'll only write these out once, and skip any futher entries
# that may be found. # that may be found.
my $written_ips = {}; my $written_ips = {};
@ -4955,9 +4983,6 @@ sub update_hosts
{ {
if ($line ne "127.0.0.1\tlocalhost localhost.localdomain localhost4 localhost4.localdomain4") if ($line ne "127.0.0.1\tlocalhost localhost.localdomain localhost4 localhost4.localdomain4")
{ {
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { changes => $changes }});
if (not $added_lo_ipv4) if (not $added_lo_ipv4)
{ {
$new_body .= "127.0.0.1\tlocalhost localhost.localdomain localhost4 localhost4.localdomain4\n"; $new_body .= "127.0.0.1\tlocalhost localhost.localdomain localhost4 localhost4.localdomain4\n";
@ -4977,9 +5002,6 @@ sub update_hosts
{ {
if ($line ne "::1\t\tlocalhost localhost.localdomain localhost6 localhost6.localdomain6") if ($line ne "::1\t\tlocalhost localhost.localdomain localhost6 localhost6.localdomain6")
{ {
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { changes => $changes }});
if (not $added_lo_ipv6) if (not $added_lo_ipv6)
{ {
$new_body .= "::1\t\tlocalhost localhost.localdomain localhost6 localhost6.localdomain6\n"; $new_body .= "::1\t\tlocalhost localhost.localdomain localhost6 localhost6.localdomain6\n";
@ -5019,8 +5041,6 @@ sub update_hosts
if (exists $written_ips->{$ip_address}) if (exists $written_ips->{$ip_address})
{ {
# Skipping at least one line, rewrite the file. # Skipping at least one line, rewrite the file.
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { changes => $changes }});
next; next;
} }
$written_ips->{$ip_address} = 1; $written_ips->{$ip_address} = 1;
@ -5049,8 +5069,6 @@ sub update_hosts
new_ip => $ip_address, new_ip => $ip_address,
host => $name, host => $name,
}}); }});
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { changes => $changes }});
next; next;
} }
} }
@ -5092,11 +5110,9 @@ sub update_hosts
my $header = $anvil->Words->string({key => "message_0177"}); my $header = $anvil->Words->string({key => "message_0177"});
$header =~ s/^\n//; $header =~ s/^\n//;
$new_body = $header.$new_body; $new_body = $header.$new_body;
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => {
's1:changes' => $changes, 's1:header' => $header,
's2:header' => $header, 's2:new_body' => $new_body,
's3:new_body' => $new_body,
}}); }});
} }
@ -5132,9 +5148,6 @@ sub update_hosts
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { new_line_count => $new_line_count }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { new_line_count => $new_line_count }});
if ($new_line_count) if ($new_line_count)
{ {
$changes = 1;
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { changes => $changes }});
$new_body .= "\n";
#$new_body .= "\n# ".$anvil->Words->string({key => "message_0178", variables => { date => $anvil->Get->date_and_time({debug => $debug}) }})."\n"; #$new_body .= "\n# ".$anvil->Words->string({key => "message_0178", variables => { date => $anvil->Get->date_and_time({debug => $debug}) }})."\n";
foreach my $ip_address (@{$ip_order}) foreach my $ip_address (@{$ip_order})
@ -5144,11 +5157,10 @@ sub update_hosts
} }
} }
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { $difference = "";
's1:changes' => $changes, $difference = diff \$old_body, \$new_body, { STYLE => 'Unified' };
's2:new_body' => $new_body, $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { difference => $difference }});
}}); if ($difference)
if ($changes)
{ {
# Write the new file. # Write the new file.
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { new_body => $new_body }}); $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => $debug, list => { new_body => $new_body }});

@ -44,6 +44,7 @@ $anvil->data->{switches}{uuid} = "";
$anvil->data->{switches}{ram} = ""; $anvil->data->{switches}{ram} = "";
$anvil->data->{switches}{'storage-group'} = ""; $anvil->data->{switches}{'storage-group'} = "";
$anvil->data->{switches}{'storage-size'} = ""; $anvil->data->{switches}{'storage-size'} = "";
$anvil->data->{switches}{'use-image'} = "";
$anvil->Get->switches; $anvil->Get->switches;
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }}); $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 2, secure => 0, key => "log_0115", variables => { program => $THIS_FILE }});
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { $anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => {

Loading…
Cancel
Save