Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save caseydentinger/2a028571516a2190f58046992688f572 to your computer and use it in GitHub Desktop.
Save caseydentinger/2a028571516a2190f58046992688f572 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
# frack-puppet:files/default/usr/local/bin/rsync_blaster
# omg this will be replaced by salt ASAP, someday...please
use strict;
use Getopt::Std;
use IPC::Open3;
use IO::Select;
use FrDeploy;
# read config file
my ($project,$program,$sync) = FrDeploy::readconf();
# exit unless invoked as the configured local_user
FrDeploy::checkuser($program->{'local_user'});
# collect command-line options
my $ident = ($0 =~ /([^\/]+)$/) ? $1 : $0;
my $arguments = join(' ',@ARGV);
our ($opt_d,$opt_h,$opt_i,$opt_t);
getopts ("dhit");
# set rsync flags
my $rsync_args = (defined $opt_t) ? "-n $program->{'rsync_args'}" : $program->{'rsync_args'};
# print project/role (i)nformation and exit
if (defined $opt_i) {
print "\nPROJECTS:\n";
for my $proj_name (sort keys %{$project}) {
my $src = "$project->{$proj_name}->{'dir'}/$project->{$proj_name}->{'loc'}";
my $dest = (defined $project->{$proj_name}->{'rsync-to'}) ? $project->{$proj_name}->{'rsync-to'} : $src;
print " $proj_name\n" .
" repo: $project->{$proj_name}->{'repo'}\n" .
" branch: $project->{$proj_name}->{'branch'}\n" .
" src: $src\n" .
" dest: $dest\n";
if (defined $project->{$proj_name}->{'service-restart'}) {
print " restart: $project->{$proj_name}->{'service-restart'}\n";
}
}
print "\nROLES:\n";
for my $role (sort keys %{$sync}) {
print " $role\n" .
" hosts: " . join(' ', @{$sync->{$role}->{'hosts'}}) . "\n" .
" projects:";
for my $proj_name (@{$sync->{$role}->{'projects'}}) {
if (defined $project->{$proj_name}) {
print " $proj_name";
} else {
print " (${proj_name})";
}
}
print "\n";
}
exit;
}
# figure out the mess that the user requested
my $rsync_jobs;
for my $chunk (@ARGV) {
$rsync_jobs = FrDeploy::get_jobs_from_sync_args($sync,$chunk,$rsync_jobs);
}
# if there weren't any jobs (or if the user threw the -h help flag) print usage info and exit
if ((defined $opt_h) or ! (defined $rsync_jobs)) {
print "\n Usage: $ident [OPTION] [TARGET]:[PROJECT] [TARGET2]:[PROJECT2]\n\n" .
" TARGET:\n" .
" host1,host2 comma separated list of individual hosts\n" .
" role all configured hosts for a given role\n" .
" ALL all configured hosts with a given project\n\n" .
" PROJECT:\n" .
" proj1,proj2 comma separated list of individual projects\n" .
" ALL all configured projects\n\n" .
" OPTION:\n" .
" -d echo the rsync commands as they're issued\n" .
" -h print helpful help\n" .
" -i information about projects and host roles\n" .
" -t rsync test run, not actual transfers\n\n" .
" EXAMPLES:\n" .
" $ident ALL:twig sync twig to every host where it is installed\n" .
" $ident host1,host2:twig sync twig to host1 and host2\n" .
" $ident payments:twig,stick sync twig&stick to all 'payments' hosts\n" .
" $ident payments1002:ALL sync all projects to payments1002\n" .
" $ident ALL:ALL sync every project to every host\n" .
"\n";
if ((defined $ARGV[0]) or (defined $opt_t)) {
my $args = (defined $ARGV[0]) ? join(' ',@ARGV) : '';
print " No jobs found for your command arguments: '$args'\n\n";
}
exit;
}
# present the user the list of rsync jobs about to happen and ask for confirmation
print "\nPlease confirm what we're about to sync\n\n";
print " Test mode, no data will transfer\n" if defined $opt_t;
for my $h (sort keys %{$rsync_jobs}) {
print " $h: " . join (' ', sort keys %{$rsync_jobs->{$h}}) . "\n";
}
my $proceed = FrDeploy::affirm("Look ok? Enter the following 4-digit key if you're sure:",FrDeploy::random_key(4));
if ($proceed eq "no") {
print "\nOk, exiting.\n\n";
exit;
}
# run the rsync jobs, and collect a list of host+project that should be restarted
FrDeploy::printlog('log_to_irc',"$ident: $arguments");
my $restart;
for my $h (sort keys %{$rsync_jobs}) {
print "\n$h\n";
for my $proj_name (sort keys %{$rsync_jobs->{$h}}) {
my $src = "$project->{$proj_name}->{'dir'}/$project->{$proj_name}->{'loc'}";
my $dest = (defined $project->{$proj_name}->{'rsync-to'}) ? $project->{$proj_name}->{'rsync-to'} : $src;
$project->{$proj_name}->{'debug'} = 1 if defined $opt_d; # populate 'debug' flag for project
print "\n $src -> $h:$dest\n";
FrDeploy::execute_shell($project->{$proj_name},"rsync $rsync_args $src/ $program->{'remote_user'}\@$h:$dest/");
push @{$restart->{$proj_name}}, $h if defined $project->{$proj_name}->{'service-restart'};
}
}
# if there are restart jobs, present the list and ask the user to confirm them
print "\nWe need to restart some stuff\n\n" if keys %{$restart};
for my $proj_name (keys %{$restart}) {
print " command: \"$project->{$proj_name}->{'service-restart'}\"\n";
print " hosts: " . join(' ', @{$restart->{$proj_name}}) . "\n";
my $proceed = FrDeploy::affirm("Look ok? Enter 'yes' if you're sure:",'yes');
if ($proceed eq 'yes') {
# cycle through all the restart jobs and fire them off one at a time
for my $h (@{$restart->{$proj_name}}) {
FrDeploy::printlog('log_to_irc',"$ident: ssh $program->{'remote_user'}\@$h $project->{$proj_name}->{'service-restart'}");
FrDeploy::execute_shell($project->{$proj_name},"ssh $program->{'remote_user'}\@$h \"$project->{$proj_name}->{'service-restart'}\"");
}
} else {
print "\nskipped.\n\n";
}
}
print "\ndone!\n\n";
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment