Created
July 18, 2016 22:42
-
-
Save caseydentinger/2a028571516a2190f58046992688f572 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 " [31m(${proj_name})[0m"; | |
} | |
} | |
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 " [31mNo jobs found for your command arguments: '$args'[0m\n\n"; | |
} | |
exit; | |
} | |
# present the user the list of rsync jobs about to happen and ask for confirmation | |
print "\n[1mPlease confirm what we're about to sync[0m\n\n"; | |
print " Test mode, no data will transfer\n" if defined $opt_t; | |
for my $h (sort keys %{$rsync_jobs}) { | |
print " [32m$h:[0m " . 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[1m$h[0m\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 [1m$src -> $h:$dest[0m\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 "\n[1mWe need to restart some stuff[0m\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 "\n[1mdone![0m\n\n"; | |
exit; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment