📄 mmm_get_dump
字号:
#!/usr/bin/env perl# Use mandatory external modulesuse strict;use Cwd;use File::Basename;use Data::Dumper;use POSIX;use Config;use Getopt::Long;# Determine installation dir nameour $SELF_DIR = dirname(dirname(Cwd::abs_path(__FILE__)));# Include parts of the systemrequire $SELF_DIR . '/lib/config.pm';require $SELF_DIR . '/lib/log.pm';#-----------------------------------------------------------------#Parse optionsmy $config_file = "mmm_lvm.conf";my $host_name;my $copy_method;my $dest_dir;GetOptions("config=s" => \$config_file, "host=s" => \$host_name, "copy-method=s" => \$copy_method, "dest-dir=s" => \$dest_dir);#-----------------------------------------------------------------# Read config fileour $config = ReadConfig($config_file);# Directories info parsingmy @clone_dirs = split(/\,/, $config->{clone_dirs});$config->{clone_dirs} = \@clone_dirs;$config->{dest_dir} = $dest_dir if ($dest_dir ne '');# Get params$copy_method = $config->{default_copy_method} unless ($copy_method);# Check host namemy $host = $config->{host}->{$host_name};PrintUsage() unless ($host);# Check copy methodmy $method = $config->{copy_method}->{$copy_method};PrintUsage() unless ($method);LogNotice("Host: '$host_name'");LogNotice("Copy method: '$copy_method'");LogNotice("-----------------------------------------------------------------");# Check destination directorymy $res = CheckDestinationDirectory();unless ($res =~ /^OK/) { LogError("Destination directory error: $res"); exit(1);}LogNotice("-----------------------------------------------------------------");# Check remote ssh connectionmy $res = CheckRemoteSshConnection($host_name);unless ($res =~ /^OK/) { LogError("SSH Check Error: $res"); exit(1);}LogNotice("-----------------------------------------------------------------");# Create and mount remote snapshot$res = CreateRemoteSnapshot($host_name);unless ($res =~ /^OK/) { LogError("Can't create snapshot: $res"); exit(1);}LogNotice("-----------------------------------------------------------------");# Perform copyingif ($config->{copy_method}->{$copy_method}->{single_run} eq 'yes') { $res = CopyFilesFromRemoteSingleRun($host_name, $copy_method, \@clone_dirs); unless ($res =~ /^OK/) { LogError("Can't copy files from remote host directories (single run): $res"); }} else { foreach my $dir (@clone_dirs) { $res = CopyFilesFromRemote($host_name, $copy_method, $dir); unless ($res =~ /^OK/) { LogError("Can't copy files from remote host directory $dir: $res"); } }}# copy _mmm dir from remote$res = CopyFilesFromRemote($host_name, 'scp', '_mmm');unless ($res =~ /^OK/) { LogError("Can't copy files from remote host _mmm directory: $res");}# save copy method to dump$res = SaveCopyMethod();unless ($res =~ /^OK/) { LogError("Can't save current copy method to _mmm directory: $res");}LogNotice("-----------------------------------------------------------------");# Perform cleanup$res = RemoveRemoteSnapshot($host_name);unless ($res =~ /^OK/) { LogWarning("WARNING!!! Can't delete remote snapshot: $res");}LogNotice("-----------------------------------------------------------------");LogNotice("Backup done!\n\n\n");exit(0);#-----------------------------------------------------------------sub PrintUsage() { print "Usage: $0 --host <host> [--copy-method method] [--dest-dir dir]\n"; print "Where:\n"; print " Host = " . join('|', keys(%{$config->{host}})) . "\n"; print " Copy method = " . join('|', keys(%{$config->{copy_method}})) . " (default = $config->{default_copy_method})\n\n"; exit(1);}#-----------------------------------------------------------------sub SaveCopyMethod() { my $dir = $config->{dest_dir} . '/_mmm'; # Check config option if (! -d $dir) { return "ERROR: No local _mmm directory in destdir!"; } open(F, ">$dir/copy_method.txt") || return "ERROR: I/O Error while saving method info!"; print F $copy_method; close(F); return "OK: Sopy method saved";}#-----------------------------------------------------------------sub CheckDestinationDirectory() { my $dir = $config->{dest_dir}; # Check config option if (!$dir) { return "ERROR: No local directory specified. Please review your config file and put 'dest_dir' option there!"; } LogNotice("Checking destination directory '$dir'..."); # Check dir system("mkdir -p $dir"); unless (-d $dir && -x $dir && -r $dir && -w $dir) { return "ERROR: Destination dir '$dir' has invalid permissions (show be readable/writable)!"; } #FIXME: need to check free space, etc here return "OK: Directory is ok";}#-----------------------------------------------------------------sub CheckRemoteSshConnection($) { my $host_name = shift; my $host = $config->{host}->{$host_name}; # Check ssh connection my $ssh_host = $host->{ssh_user} . '@' . $host->{ip}; my $check_cmd = "ssh $ssh_host date"; LogNotice("Verifying ssh connection to remote host '$ssh_host' (command: $check_cmd)..."); $res = system($check_cmd); if ($res) { return "Can't execute remote commands on host $host_name($ssh_host): $!\n"; } return "OK: SSH connection works fine!";}#-----------------------------------------------------------------sub CreateRemoteSnapshot($) { my $host_name = shift; my $host = $config->{host}->{$host_name}; my $ssh_host = $host->{ssh_user} . '@' . $host->{ip}; my $mmm_dir = $host->{mmm_dir} || "/usr/local/mmm"; # Create and mount snapshot on remote host LogDebug("Executing create_snapshot on remote server '$host_name'..."); chomp($res = `ssh "$ssh_host" "$mmm_dir/bin/lvm/create_snapshot"`); print "$res\n"; my @res_lines = split(/\n/, $res); my $last_line = pop(@res_lines); return $last_line;}#-----------------------------------------------------------------sub CopyFilesFromRemote($$$) { my $host_name = shift; my $copy_method = shift; my $subdir = shift; my $host = $config->{host}->{$host_name}; my $ssh_host = $host->{ssh_user} . '@' . $host->{ip}; LogNotice("Copying files from remote host $host_name with method $copy_method from subdir $subdir of snapshot..."); my $copy = $config->{copy_method}->{$copy_method}; my $copy_cmd = $copy->{command}; LogDebug("Performing template substitutions on command..."); $copy_cmd =~ s/%SSH_USER%/$host->{ssh_user}/ig; $copy_cmd =~ s/%IP%/$host->{ip}/ig; $copy_cmd =~ s/%SNAPSHOT%/$host->{lvm_mount_dir}/ig; $copy_cmd =~ s/%DEST_DIR%/$config->{dest_dir}/ig; $copy_cmd =~ s/%CLONE_DIR%/$subdir/ig; LogDebug("Final command: '$copy_cmd'"); my $res = system($copy_cmd); if ($res) { return "ERROR: Can't perform copy operation: $!"; } return "OK: Copy is finished!";}#-----------------------------------------------------------------sub CopyFilesFromRemoteSingleRun($$$) { my $host_name = shift; my $copy_method = shift; my $clone_dirs = shift; @clone_dirs = @$clone_dirs; my $host = $config->{host}->{$host_name}; my $ssh_host = $host->{ssh_user} . '@' . $host->{ip}; LogNotice("Copying files from remote host $host_name with method $copy_method from remote directories of snapshot..."); my $copy = $config->{copy_method}->{$copy_method}; my $copy_cmd = $copy->{command}; LogDebug("Performing template substitutions on command..."); $copy_cmd =~ s/%SSH_USER%/$host->{ssh_user}/ig; $copy_cmd =~ s/%IP%/$host->{ip}/ig; $copy_cmd =~ s/%SNAPSHOT%/$host->{lvm_mount_dir}/ig; $copy_cmd =~ s/%DEST_DIR%/$config->{dest_dir}/ig; if ($copy_cmd =~ /!(.*)!/) { my $sub_tmpl = $1; my $sub_cmd = ""; for my $dir (@clone_dirs) { my $partial = $sub_tmpl; $partial =~ s/%CLONE_DIR%/$dir/ig; $sub_cmd .= " $partial"; } $copy_cmd =~ s/!.*!/$sub_cmd/; } LogDebug("Final command: '$copy_cmd'"); my $res = system($copy_cmd); if ($res) { system("rdiff-backup --check-destination-dir '$config->{dest_dir}'"); return "ERROR: Can't perform single-run copy operation: $!"; } return "OK: Copy is finished!";}#-----------------------------------------------------------------sub RemoveRemoteSnapshot($) { my $host_name = shift; my $host = $config->{host}->{$host_name}; my $ssh_host = $host->{ssh_user} . '@' . $host->{ip}; my $mmm_dir = $host->{mmm_dir} || "/usr/local/mmm"; # Umount and remove snapshot on remote host LogDebug("Executing remove_snapshot on remote server '$host_name'..."); chomp($res = `ssh "$ssh_host" "$mmm_dir/bin/lvm/remove_snapshot"`); print "$res\n"; my @res_lines = split(/\n/, $res); my $last_line = pop(@res_lines); return $last_line;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -