Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[CHANGED] made it work... :D

  • Loading branch information...
commit e1d02fe4846a5221de67ab2fcac4da756e7c5192 1 parent 11a117d
Tobias Kirschstein authored
13 bin/gio
View
@@ -34,16 +34,17 @@ foreach my $line (keys %{$config}) {
$cnf->{$name}->{$key} = $config->{$line};
}
-my $gio = Giovanni->new(debug => $debug);
-foreach my $task (keys %{$cnf}) {
+foreach my $project (keys %{$cnf}) {
+ my $gio = Giovanni->new(debug => $debug, config => $cnf->{$project});
+
given ($command) {
when ('deploy') {
- print "{task} Running deploy for '$task'\n";
- $gio->deploy($cnf->{$task});
+ print "Running deploy for '$project'\n";
+ $gio->deploy;
}
when ('rollback') {
- print "{task} Running rollback for '$task'\n";
- $gio->rollback($cnf->{$task}, $offset);
+ print "Running rollback for '$project'\n";
+ $gio->rollback($offset);
}
default { print "Could not find command '$command'\n"; }
}
86 lib/Giovanni.pm
View
@@ -16,11 +16,11 @@ Giovanni - The great new Giovanni!
=head1 VERSION
-Version 0.6
+Version 0.7
=cut
-our $VERSION = '0.6';
+our $VERSION = '0.7';
has 'debug' => (
is => 'rw',
@@ -33,7 +33,8 @@ has 'debug' => (
has 'hostname' => (
is => 'rw',
isa => 'Str',
- default => hostname());
+ default => hostname(),
+);
has 'repo' => (
is => 'rw',
@@ -71,6 +72,11 @@ has 'error' => (
isa => 'Str',
);
+has 'config' => (
+ is => 'rw',
+ required => 1,
+);
+
=head1 SYNOPSIS
Quick summary of what the module does.
@@ -94,62 +100,68 @@ if you don't export anything, such as for a purely object-oriented module.
=cut
sub deploy {
- my ($self, $conf) = @_;
+ my ($self) = @_;
# load SCM plugin
$self->load_plugin($self->scm);
- my $tag = $self->tag();
- my @hosts = split(/\s*,\s*/, $conf->{hosts});
- my $ssh = $self->_get_ssh_conn($conf);
- foreach my $host (@hosts) {
- $self->process_stages($ssh->{$host}, $conf, 'deploy');
- }
+ my $tag = $self->tag();
+ my $ssh = $self->_get_ssh_conn;
+ $self->process_stages($ssh, 'deploy');
+}
+
+=head2 rollback
+
+=cut
+sub rollback {
+ my ($self, $offset) = @_;
+
+ my $ssh = $self->_get_ssh_conn;
+ $self->process_stages($ssh, 'rollback');
}
sub process_stages {
- my ($self, $ssh, $conf, $mode) = @_;
+ my ($self, $ssh, $mode) = @_;
- my @stages = split(/\s*,\s*/, $conf->{$mode});
+ my @stages = split(/\s*,\s*/, $self->config->{$mode});
foreach my $stage (@stages) {
- print "[" . $ssh->get_host . "] running $stage\n";
- $self->$stage($ssh, $conf);
-
- # TODO we need a robust error handling here
- confess $self->error if $self->error;
+ $self->process_hosts($ssh, $stage, $mode);
+
+ # if one host produced an error while restarting, rollback all
+ if ($self->error and ($stage =~ m/^restart/i) and ($mode eq 'deploy')) {
+ $self->log('ERROR', $self->error);
+ $self->process_stages($ssh, 'rollback');
+ return;
+ }
}
}
-=head2 rollback
-
-=cut
+sub process_hosts {
+ my ($self, $ssh, $stage, $mode) = @_;
-sub rollback {
- my ($self, $conf, $offset) = @_;
-
- my @hosts = split(/\s*,\s*/, $conf->{hosts});
- my $ssh = $self->_get_ssh_conn($conf);
+ my @hosts = split(/\s*,\s*/, $self->config->{hosts});
foreach my $host (@hosts) {
- $self->process_stages($ssh->{$host}, $conf, 'rollback');
+ $self->log($ssh->{$host}, "running $stage");
+ $self->$stage($ssh->{$host});
}
}
sub _get_ssh_conn {
- my ($self, $conf) = @_;
+ my ($self) = @_;
- my @hosts = split(/\s*,\s*/, $conf->{hosts});
+ my @hosts = split(/\s*,\s*/, $self->config->{hosts});
my $ssh;
foreach my $host (@hosts) {
my $conn = $host;
- $conn = ($conf->{user} || $self->user) . '@' . $host;
+ $conn = ($self->config->{user} || $self->user) . '@' . $host;
$ssh->{$host} = Net::OpenSSH->new($conn, async => 1);
}
# trigger noop command to check for connection
foreach my $host (@hosts) {
- $ssh->{$host}->system('echo')
+ $ssh->{$host}->test('echo')
or confess "could not connect to $host: " . $ssh->{$host}->error;
- print "[$host] connected\n";
+ $self->log($host, 'connected');
}
return $ssh;
}
@@ -169,21 +181,23 @@ sub load_plugin {
print STDERR "Loading $plugin Plugin\n" if $self->is_debug;
with($plug); # or confess "Could not load Plugin: '$plugin'\n";
}
+
return;
}
-sub logger {
+sub log {
my ($self, $host, $log) = @_;
return unless $log;
+
my $name;
given ($host) {
- when (ref $host eq 'SCALAR') { $name = $host; }
- default { $name = $host->get_host; }
+ when (ref $host eq 'Net::OpenSSH') { $name = $host->get_host; }
+ default { $name = $host; }
}
chomp($log);
- print STDERR "*log* [" . $name . "] ";
- print STDERR $log . "\n";
+ print STDERR "[" . $name . "] " . $log . $/;
+
return;
}
67 lib/Giovanni/Plugins/Git.pm
View
@@ -7,7 +7,7 @@ has 'git' => (
is => 'rw',
isa => 'Git::Repository',
lazy => 1,
- default => sub { Git::Repository->new( work_tree => $_[0]->repo ) },
+ default => sub { Git::Repository->new(work_tree => $_[0]->repo) },
);
sub tag {
@@ -15,24 +15,26 @@ sub tag {
my $tag = 'v' . time;
my $log =
- $self->git->run( tag => '-a', $tag, '-m', "tagging to $tag for rollout" );
- print STDERR "Tag: [$tag] " . $log . "\n" if $self->is_debug;
+ $self->git->run(tag => '-a', $tag, '-m', "tagging to $tag for rollout");
+ $self->log('git', "Tag: [$tag] " . $log) if $self->is_debug;
$log = $self->git->run('pull') unless $self->is_debug;
- print STDERR "Pull: " . $log . "\n" if $self->is_debug;
- $log = $self->git->run( push => 'origin', '--tags' ) unless $self->is_debug;
- print STDERR "Push: " . $log . "\n" if $self->is_debug;
+ $self->log('git', "Pull: " . $log) if $self->is_debug;
+ $log = $self->git->run(push => 'origin', '--tags') unless $self->is_debug;
+ $self->log('git', "Push: " . $log) if $self->is_debug;
$self->version($tag);
- $self->logger('localhost', $log);
+ $self->log('git', $log);
+
return $tag;
}
sub get_last_tag {
- my ( $self, $n ) = @_;
+ my ($self, $n) = @_;
$n = 1 unless $n;
my @tags = $self->git->run('tag');
- print STDERR "Tags: " . join( ', ', @tags ) . "\n" if $self->is_debug;
- return splice( @tags, $n-1, $n );
+ $self->log('git', "Tags: " . join(', ', @tags) . $/) if $self->is_debug;
+
+ return splice(@tags, $n - 1, $n);
}
around 'update_cache' => sub {
@@ -40,36 +42,45 @@ around 'update_cache' => sub {
my $log;
my $cache_dir = $self->_get_cache_dir($conf);
- if($conf->{cache}){
- if($ssh->test("[ -d ".$cache_dir." ]")){
- $log .= $ssh->capture("cd $cache_dir && git pull" );
- print "[".$ssh->get_host."] running git pull ...\n";
- }else{
- $log = $ssh->capture("mkdir -p ".$conf->{cache})
- unless $ssh->test("[ -d ".$conf->{cache}." ]");
- $log .= $ssh->capture("git clone ".$conf->{repo}." $cache_dir" );
- print "[".$ssh->get_host."] running git clone ...\n";
+ if ($self->config->{cache}) {
+ if ($ssh->test("[ -d " . $cache_dir . " ]")) {
+ $log .= $ssh->capture("cd $cache_dir && git pull");
+ $self->log("running git pull ...");
+ }
+ else {
+ $log = $ssh->capture("mkdir -p " . $self->config->{cache})
+ unless $ssh->test("[ -d " . $self->config->{cache} . " ]");
+ $log .= $ssh->capture(
+ "git clone " . $self->config->{repo} . " $cache_dir");
+ $self->log("running git clone ...");
}
}
- $self->logger($ssh, $log);
+ $self->log($ssh, $log);
+
return;
};
-around 'checkout' => sub {
+around 'checkout' => sub {
my ($orig, $self, $ssh, $conf) = @_;
+
my $log;
my $cache_dir = $self->_get_cache_dir($conf);
- if($conf->{root}){
- $log .= $ssh->capture("cd ".$conf->{root}." && git clone --depth 1 --no-hardlinks file://".$cache_dir." ." );
- }
- $self->logger($ssh, $log);
+ if ($self->config->{deploy_dir}) {
+ $log .=
+ $ssh->capture("cd "
+ . $self->config->{deploy_dir}
+ . " && git clone --depth 1 --no-hardlinks file://"
+ . $cache_dir
+ . " .");
+ }
+ $self->log($ssh, $log);
};
sub _get_cache_dir {
my ($self, $conf) = @_;
- my @parts = split(/\//, $conf->{repo});
+ my @parts = split(/\//, $self->config->{repo});
my $git_dir = pop(@parts);
- return join('/', $conf->{cache}, $git_dir);
+ return join('/', $self->config->{cache}, $git_dir);
}
-__PACKAGE__
+1;
161 lib/Giovanni/Stages.pm
View
@@ -11,149 +11,178 @@ use Data::Dumper;
# rethink this approach.
sub update_cache {
- my ($self, $ssh, $conf) = @_;
- print "[".$ssh->get_host."] running update_cache task ...\n";
+ my ($self, $ssh) = @_;
+ $self->log($ssh, "running update_cache task ...");
return;
}
sub rollout {
- my ($self, $ssh, $conf) = @_;
- print "[".$ssh->get_host."] running rollout task ...\n";
- my $log = $ssh->capture("mkdir -p ".$conf->{root});
- $self->logger($ssh, $log);
- $self->checkout($ssh, $conf);
+ my ($self, $ssh) = @_;
+
+ $self->log($ssh, "running rollout task ...");
+ $self->config->{deploy_dir} = $self->config->{root};
+ my $log = $ssh->capture("mkdir -p " . $self->config->{deploy_dir});
+ $self->log($ssh, $log);
+ $self->checkout($ssh);
+
return;
}
sub rollout_timestamped {
- my ($self, $ssh, $conf) = @_;
+ my ($self, $ssh) = @_;
+
+ $self->log($ssh, "running rollout_timestamped task ...");
+ my $deploy_dir = join('/', $self->config->{root}, 'releases', time);
+ my $current = join('/', $self->config->{root}, 'current');
+ my $log = $ssh->capture("mkdir -p " . $deploy_dir);
+ $log .= $ssh->capture(
+ "unlink " . $current . "; ln -s " . $deploy_dir . " " . $current);
+ $self->config->{deploy_dir} = $deploy_dir;
+ $self->log($ssh, $log);
+ $self->checkout($ssh);
- my $deploy_dir = join('/', $conf->{root}, 'releases', time);
- my $current = join('/', $conf->{root}, 'current');
- my $log = $ssh->capture("mkdir -p ".$deploy_dir);
- $log .= $ssh->capture("unlink ".$current."; ln -s ".$deploy_dir." ".$current);
- $conf->{root} = $deploy_dir;
- print "[".$ssh->get_host."] running rollout_timestamped task ...\n";
- $self->logger($ssh, $log);
- $self->checkout($ssh, $conf);
return;
}
sub rollback_timestamped {
- my ($self, $ssh, $conf, $offset) = @_;
- my $deploy_dir = join('/', $conf->{root}, 'releases');
- my $current = join('/', $conf->{root}, 'current');
- print "[".$ssh->get_host."] running rollback task ...\n";
- my @rels = $ssh->capture("ls -1 ".$deploy_dir);
+ my ($self, $ssh, $offset) = @_;
+
+ $self->log($ssh, "running rollback task ...");
+ my $deploy_dir = join('/', $self->config->{root}, 'releases');
+ my $current = join('/', $self->config->{root}, 'current');
+ my @rels = $ssh->capture("ls -1 " . $deploy_dir);
@rels = sort(@rels);
- my $link = $ssh->capture("ls -l ".$current." | sed 's/^.*->\\s*//'");
+ my $link = $ssh->capture("ls -l " . $current . " | sed 's/^.*->\\s*//'");
my @path = split(/\//, $link);
my $current_rel = pop(@path);
my (@past, @future);
- foreach my $rel (@rels){
+
+ foreach my $rel (@rels) {
chomp($rel);
next unless $rel =~ m{^\w};
- if($rel == $current_rel){
+ if ($rel == $current_rel) {
push(@future, $rel);
next;
}
- if(@future){
+ if (@future) {
push(@future, $rel);
- } else {
+ }
+ else {
push(@past, $rel);
}
}
- $deploy_dir = join('/', $conf->{root}, pop(@past));
- my $log = $ssh->capture("unlink ".$current."; ln -s ".$deploy_dir." ".$current);
- $self->logger($ssh, $log);
+ $deploy_dir = join('/', $self->config->{root}, pop(@past));
+ my $log = $ssh->capture(
+ "unlink " . $current . "; ln -s " . $deploy_dir . " " . $current);
+ $self->log($ssh, $log);
return;
}
sub rollback_scm {
- my ( $self, $ssh, $conf, $offset ) = @_;
+ my ($self, $ssh, $offset) = @_;
# load SCM plugin
- $self->load_plugin( $self->scm );
+ $self->load_plugin($self->scm);
my $tag = $self->get_last_tag($offset);
- print STDERR "Rolling back to tag: $tag\n" if $self->is_debug;
+ $self->log($ssh, "Rolling back to tag: $tag") if $self->is_debug;
+
# TODO change checkout to accept an optional tag so we can reuse it
# here to check out an old version.
+
return;
}
sub restart {
- my ($self, $ssh, $conf) = @_;
- my ( $pty, $pid ) = $ssh->open2pty("sudo ".$conf->{init}." restart");
+ my ($self, $ssh) = @_;
+
+ $self->log("running restart task ...");
+ my ($pty, $pid) =
+ $ssh->open2pty("sudo " . $self->config->{init} . " restart");
my $exp = Expect->init($pty);
my $ret = $exp->interact();
- print "[".$ssh->get_host."] running restart task ...\n";
- $self->logger($ssh, "restarted ...");
+ $self->log($ssh, "restarted ..." . Dumper($exp));
+
return;
}
sub checkout {
- my ($self, $ssh, $conf) = @_;
- print "[".$ssh->get_host."] running checkout task ...\n";
+ my ($self, $ssh) = @_;
+ $self->log($ssh, "running checkout task ...");
return;
}
sub cleanup_timestamped {
- my ($self, $ssh, $conf, $offset) = @_;
- print STDERR "PATH: ".$conf->{root}."\n";
- if($conf->{root} =~ m{^.*/\d+$}){
- my @path = split(/\//, $conf->{root});
+ my ($self, $ssh, $offset) = @_;
+
+ $self->log($ssh, "running cleanup task ...");
+
+ if ($self->config->{root} =~ m{^.*/\d+$}) {
+ my @path = split(/\//, $self->config->{root});
pop(@path);
pop(@path);
- $conf->{root} = join('/', @path);
+ $self->config->{root} = join('/', @path);
}
- print STDERR "PATH2: ".$conf->{root}."\n";
- my $deploy_dir = join('/', $conf->{root}, 'releases');
- my $current = join('/', $conf->{root}, 'current');
- print "[".$ssh->get_host."] running cleanup task ...\n";
- my @rels = $ssh->capture("ls -1 ".$deploy_dir);
+
+ my $deploy_dir = join('/', $self->config->{root}, 'releases');
+ my $current = join('/', $self->config->{root}, 'current');
+ my @rels = $ssh->capture("ls -1 " . $deploy_dir);
@rels = sort(@rels);
- my $link = $ssh->capture("ls -l ".$current." | sed 's/^.*->\\s*//'");
+ my $link = $ssh->capture("ls -l " . $current . " | sed 's/^.*->\\s*//'");
my @path = split(/\//, $link);
my $current_rel = pop(@path);
my (@past, @future);
- foreach my $rel (@rels){
+
+ foreach my $rel (@rels) {
chomp($rel);
next unless $rel =~ m{^\w};
- if($rel == $current_rel){
+ if ($rel == $current_rel) {
push(@future, $rel);
next;
}
- if(@future){
+ if (@future) {
push(@future, $rel);
- } else {
+ }
+ else {
push(@past, $rel);
}
}
- $deploy_dir = join('/', $conf->{root}, pop(@past));
- my $num = $conf->{keep_versions} || 5;
+ $deploy_dir = join('/', $self->config->{root}, pop(@past));
+ my $num = $self->config->{keep_versions} || 5;
my $log;
- while($#past > ($num)){
- my $to_del = join('/', $conf->{root}, 'releases', shift(@past));
- $log = $ssh->capture("rm -rf ".$to_del);
+ while ($#past > ($num)) {
+ my $to_del = join('/', $self->config->{root}, 'releases', shift(@past));
+ $self->log($ssh, "deleting $to_del");
+ $log = $ssh->capture("rm -rf " . $to_del);
}
- $self->logger($ssh, $log);
+ $self->log($ssh, $log);
+
return;
}
sub restart_phased {
my ($self, $ssh, $conf) = @_;
- my ( $pty, $pid ) = $ssh->open2pty("sudo ".$conf->{init}." restart");
- my $exp = Expect->init($pty);
- $exp->interact();
- print "[".$ssh->get_host."] running restart_phased task ...\n";
- $self->logger($ssh, "restarted ...");
+
+ $self->log($ssh, "running restart_phased task ...");
+ unless ($ssh->test("sudo " . $self->config->{init} . " restart")) {
+ $self->log(
+ 'restart failed: ' . $ssh->error . ' trying stop -> start instead');
+ $ssh->test("sudo " . $self->config->{init} . " stop");
+ $ssh->test("sudo " . $self->config->{init} . " start")
+ or $self->error('restart failed: ' . $ssh->error);
+ return;
+ }
+
+ # my $exp = Expect->init($pty);
+ # $exp->interact();
+ $self->log($ssh, 'restarted ' . $self->config->{init});
+
return;
}
sub notify {
my ($self, $ssh, $conf) = @_;
- print "[".$ssh->get_host."] running notify task ...\n";
+ $self->log($ssh, "running notify task ...");
return;
}
-__PACKAGE__
+__PACKAGE__->meta->make_immutable;
Please sign in to comment.
Something went wrong with that request. Please try again.