Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[CHANGED] made it work... :D

  • Loading branch information...
commit e1d02fe4846a5221de67ab2fcac4da756e7c5192 1 parent 11a117d
Tobias Kirschstein authored
13 bin/gio
@@ -34,16 +34,17 @@ foreach my $line (keys %{$config}) {
34 34 $cnf->{$name}->{$key} = $config->{$line};
35 35 }
36 36
37   -my $gio = Giovanni->new(debug => $debug);
38   -foreach my $task (keys %{$cnf}) {
  37 +foreach my $project (keys %{$cnf}) {
  38 + my $gio = Giovanni->new(debug => $debug, config => $cnf->{$project});
  39 +
39 40 given ($command) {
40 41 when ('deploy') {
41   - print "{task} Running deploy for '$task'\n";
42   - $gio->deploy($cnf->{$task});
  42 + print "Running deploy for '$project'\n";
  43 + $gio->deploy;
43 44 }
44 45 when ('rollback') {
45   - print "{task} Running rollback for '$task'\n";
46   - $gio->rollback($cnf->{$task}, $offset);
  46 + print "Running rollback for '$project'\n";
  47 + $gio->rollback($offset);
47 48 }
48 49 default { print "Could not find command '$command'\n"; }
49 50 }
86 lib/Giovanni.pm
@@ -16,11 +16,11 @@ Giovanni - The great new Giovanni!
16 16
17 17 =head1 VERSION
18 18
19   -Version 0.6
  19 +Version 0.7
20 20
21 21 =cut
22 22
23   -our $VERSION = '0.6';
  23 +our $VERSION = '0.7';
24 24
25 25 has 'debug' => (
26 26 is => 'rw',
@@ -33,7 +33,8 @@ has 'debug' => (
33 33 has 'hostname' => (
34 34 is => 'rw',
35 35 isa => 'Str',
36   - default => hostname());
  36 + default => hostname(),
  37 +);
37 38
38 39 has 'repo' => (
39 40 is => 'rw',
@@ -71,6 +72,11 @@ has 'error' => (
71 72 isa => 'Str',
72 73 );
73 74
  75 +has 'config' => (
  76 + is => 'rw',
  77 + required => 1,
  78 +);
  79 +
74 80 =head1 SYNOPSIS
75 81
76 82 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.
94 100 =cut
95 101
96 102 sub deploy {
97   - my ($self, $conf) = @_;
  103 + my ($self) = @_;
98 104
99 105 # load SCM plugin
100 106 $self->load_plugin($self->scm);
101   - my $tag = $self->tag();
102   - my @hosts = split(/\s*,\s*/, $conf->{hosts});
103   - my $ssh = $self->_get_ssh_conn($conf);
104   - foreach my $host (@hosts) {
105   - $self->process_stages($ssh->{$host}, $conf, 'deploy');
106   - }
  107 + my $tag = $self->tag();
  108 + my $ssh = $self->_get_ssh_conn;
  109 + $self->process_stages($ssh, 'deploy');
  110 +}
  111 +
  112 +=head2 rollback
  113 +
  114 +=cut
107 115
  116 +sub rollback {
  117 + my ($self, $offset) = @_;
  118 +
  119 + my $ssh = $self->_get_ssh_conn;
  120 + $self->process_stages($ssh, 'rollback');
108 121 }
109 122
110 123 sub process_stages {
111   - my ($self, $ssh, $conf, $mode) = @_;
  124 + my ($self, $ssh, $mode) = @_;
112 125
113   - my @stages = split(/\s*,\s*/, $conf->{$mode});
  126 + my @stages = split(/\s*,\s*/, $self->config->{$mode});
114 127 foreach my $stage (@stages) {
115   - print "[" . $ssh->get_host . "] running $stage\n";
116   - $self->$stage($ssh, $conf);
117   -
118   - # TODO we need a robust error handling here
119   - confess $self->error if $self->error;
  128 + $self->process_hosts($ssh, $stage, $mode);
  129 +
  130 + # if one host produced an error while restarting, rollback all
  131 + if ($self->error and ($stage =~ m/^restart/i) and ($mode eq 'deploy')) {
  132 + $self->log('ERROR', $self->error);
  133 + $self->process_stages($ssh, 'rollback');
  134 + return;
  135 + }
120 136 }
121 137 }
122 138
123   -=head2 rollback
124   -
125   -=cut
  139 +sub process_hosts {
  140 + my ($self, $ssh, $stage, $mode) = @_;
126 141
127   -sub rollback {
128   - my ($self, $conf, $offset) = @_;
129   -
130   - my @hosts = split(/\s*,\s*/, $conf->{hosts});
131   - my $ssh = $self->_get_ssh_conn($conf);
  142 + my @hosts = split(/\s*,\s*/, $self->config->{hosts});
132 143 foreach my $host (@hosts) {
133   - $self->process_stages($ssh->{$host}, $conf, 'rollback');
  144 + $self->log($ssh->{$host}, "running $stage");
  145 + $self->$stage($ssh->{$host});
134 146 }
135 147 }
136 148
137 149 sub _get_ssh_conn {
138   - my ($self, $conf) = @_;
  150 + my ($self) = @_;
139 151
140   - my @hosts = split(/\s*,\s*/, $conf->{hosts});
  152 + my @hosts = split(/\s*,\s*/, $self->config->{hosts});
141 153 my $ssh;
142 154 foreach my $host (@hosts) {
143 155 my $conn = $host;
144   - $conn = ($conf->{user} || $self->user) . '@' . $host;
  156 + $conn = ($self->config->{user} || $self->user) . '@' . $host;
145 157 $ssh->{$host} = Net::OpenSSH->new($conn, async => 1);
146 158 }
147 159
148 160 # trigger noop command to check for connection
149 161 foreach my $host (@hosts) {
150   - $ssh->{$host}->system('echo')
  162 + $ssh->{$host}->test('echo')
151 163 or confess "could not connect to $host: " . $ssh->{$host}->error;
152   - print "[$host] connected\n";
  164 + $self->log($host, 'connected');
153 165 }
154 166 return $ssh;
155 167 }
@@ -169,21 +181,23 @@ sub load_plugin {
169 181 print STDERR "Loading $plugin Plugin\n" if $self->is_debug;
170 182 with($plug); # or confess "Could not load Plugin: '$plugin'\n";
171 183 }
  184 +
172 185 return;
173 186 }
174 187
175   -sub logger {
  188 +sub log {
176 189 my ($self, $host, $log) = @_;
177 190
178 191 return unless $log;
  192 +
179 193 my $name;
180 194 given ($host) {
181   - when (ref $host eq 'SCALAR') { $name = $host; }
182   - default { $name = $host->get_host; }
  195 + when (ref $host eq 'Net::OpenSSH') { $name = $host->get_host; }
  196 + default { $name = $host; }
183 197 }
184 198 chomp($log);
185   - print STDERR "*log* [" . $name . "] ";
186   - print STDERR $log . "\n";
  199 + print STDERR "[" . $name . "] " . $log . $/;
  200 +
187 201 return;
188 202 }
189 203
67 lib/Giovanni/Plugins/Git.pm
@@ -7,7 +7,7 @@ has 'git' => (
7 7 is => 'rw',
8 8 isa => 'Git::Repository',
9 9 lazy => 1,
10   - default => sub { Git::Repository->new( work_tree => $_[0]->repo ) },
  10 + default => sub { Git::Repository->new(work_tree => $_[0]->repo) },
11 11 );
12 12
13 13 sub tag {
@@ -15,24 +15,26 @@ sub tag {
15 15
16 16 my $tag = 'v' . time;
17 17 my $log =
18   - $self->git->run( tag => '-a', $tag, '-m', "tagging to $tag for rollout" );
19   - print STDERR "Tag: [$tag] " . $log . "\n" if $self->is_debug;
  18 + $self->git->run(tag => '-a', $tag, '-m', "tagging to $tag for rollout");
  19 + $self->log('git', "Tag: [$tag] " . $log) if $self->is_debug;
20 20 $log = $self->git->run('pull') unless $self->is_debug;
21   - print STDERR "Pull: " . $log . "\n" if $self->is_debug;
22   - $log = $self->git->run( push => 'origin', '--tags' ) unless $self->is_debug;
23   - print STDERR "Push: " . $log . "\n" if $self->is_debug;
  21 + $self->log('git', "Pull: " . $log) if $self->is_debug;
  22 + $log = $self->git->run(push => 'origin', '--tags') unless $self->is_debug;
  23 + $self->log('git', "Push: " . $log) if $self->is_debug;
24 24 $self->version($tag);
25   - $self->logger('localhost', $log);
  25 + $self->log('git', $log);
  26 +
26 27 return $tag;
27 28 }
28 29
29 30 sub get_last_tag {
30   - my ( $self, $n ) = @_;
  31 + my ($self, $n) = @_;
31 32
32 33 $n = 1 unless $n;
33 34 my @tags = $self->git->run('tag');
34   - print STDERR "Tags: " . join( ', ', @tags ) . "\n" if $self->is_debug;
35   - return splice( @tags, $n-1, $n );
  35 + $self->log('git', "Tags: " . join(', ', @tags) . $/) if $self->is_debug;
  36 +
  37 + return splice(@tags, $n - 1, $n);
36 38 }
37 39
38 40 around 'update_cache' => sub {
@@ -40,36 +42,45 @@ around 'update_cache' => sub {
40 42
41 43 my $log;
42 44 my $cache_dir = $self->_get_cache_dir($conf);
43   - if($conf->{cache}){
44   - if($ssh->test("[ -d ".$cache_dir." ]")){
45   - $log .= $ssh->capture("cd $cache_dir && git pull" );
46   - print "[".$ssh->get_host."] running git pull ...\n";
47   - }else{
48   - $log = $ssh->capture("mkdir -p ".$conf->{cache})
49   - unless $ssh->test("[ -d ".$conf->{cache}." ]");
50   - $log .= $ssh->capture("git clone ".$conf->{repo}." $cache_dir" );
51   - print "[".$ssh->get_host."] running git clone ...\n";
  45 + if ($self->config->{cache}) {
  46 + if ($ssh->test("[ -d " . $cache_dir . " ]")) {
  47 + $log .= $ssh->capture("cd $cache_dir && git pull");
  48 + $self->log("running git pull ...");
  49 + }
  50 + else {
  51 + $log = $ssh->capture("mkdir -p " . $self->config->{cache})
  52 + unless $ssh->test("[ -d " . $self->config->{cache} . " ]");
  53 + $log .= $ssh->capture(
  54 + "git clone " . $self->config->{repo} . " $cache_dir");
  55 + $self->log("running git clone ...");
52 56 }
53 57 }
54   - $self->logger($ssh, $log);
  58 + $self->log($ssh, $log);
  59 +
55 60 return;
56 61 };
57 62
58   -around 'checkout' => sub {
  63 +around 'checkout' => sub {
59 64 my ($orig, $self, $ssh, $conf) = @_;
  65 +
60 66 my $log;
61 67 my $cache_dir = $self->_get_cache_dir($conf);
62   - if($conf->{root}){
63   - $log .= $ssh->capture("cd ".$conf->{root}." && git clone --depth 1 --no-hardlinks file://".$cache_dir." ." );
64   - }
65   - $self->logger($ssh, $log);
  68 + if ($self->config->{deploy_dir}) {
  69 + $log .=
  70 + $ssh->capture("cd "
  71 + . $self->config->{deploy_dir}
  72 + . " && git clone --depth 1 --no-hardlinks file://"
  73 + . $cache_dir
  74 + . " .");
  75 + }
  76 + $self->log($ssh, $log);
66 77 };
67 78
68 79 sub _get_cache_dir {
69 80 my ($self, $conf) = @_;
70   - my @parts = split(/\//, $conf->{repo});
  81 + my @parts = split(/\//, $self->config->{repo});
71 82 my $git_dir = pop(@parts);
72   - return join('/', $conf->{cache}, $git_dir);
  83 + return join('/', $self->config->{cache}, $git_dir);
73 84 }
74 85
75   -__PACKAGE__
  86 +1;
161 lib/Giovanni/Stages.pm
@@ -11,149 +11,178 @@ use Data::Dumper;
11 11 # rethink this approach.
12 12
13 13 sub update_cache {
14   - my ($self, $ssh, $conf) = @_;
15   - print "[".$ssh->get_host."] running update_cache task ...\n";
  14 + my ($self, $ssh) = @_;
  15 + $self->log($ssh, "running update_cache task ...");
16 16 return;
17 17 }
18 18
19 19 sub rollout {
20   - my ($self, $ssh, $conf) = @_;
21   - print "[".$ssh->get_host."] running rollout task ...\n";
22   - my $log = $ssh->capture("mkdir -p ".$conf->{root});
23   - $self->logger($ssh, $log);
24   - $self->checkout($ssh, $conf);
  20 + my ($self, $ssh) = @_;
  21 +
  22 + $self->log($ssh, "running rollout task ...");
  23 + $self->config->{deploy_dir} = $self->config->{root};
  24 + my $log = $ssh->capture("mkdir -p " . $self->config->{deploy_dir});
  25 + $self->log($ssh, $log);
  26 + $self->checkout($ssh);
  27 +
25 28 return;
26 29 }
27 30
28 31 sub rollout_timestamped {
29   - my ($self, $ssh, $conf) = @_;
  32 + my ($self, $ssh) = @_;
  33 +
  34 + $self->log($ssh, "running rollout_timestamped task ...");
  35 + my $deploy_dir = join('/', $self->config->{root}, 'releases', time);
  36 + my $current = join('/', $self->config->{root}, 'current');
  37 + my $log = $ssh->capture("mkdir -p " . $deploy_dir);
  38 + $log .= $ssh->capture(
  39 + "unlink " . $current . "; ln -s " . $deploy_dir . " " . $current);
  40 + $self->config->{deploy_dir} = $deploy_dir;
  41 + $self->log($ssh, $log);
  42 + $self->checkout($ssh);
30 43
31   - my $deploy_dir = join('/', $conf->{root}, 'releases', time);
32   - my $current = join('/', $conf->{root}, 'current');
33   - my $log = $ssh->capture("mkdir -p ".$deploy_dir);
34   - $log .= $ssh->capture("unlink ".$current."; ln -s ".$deploy_dir." ".$current);
35   - $conf->{root} = $deploy_dir;
36   - print "[".$ssh->get_host."] running rollout_timestamped task ...\n";
37   - $self->logger($ssh, $log);
38   - $self->checkout($ssh, $conf);
39 44 return;
40 45 }
41 46
42 47 sub rollback_timestamped {
43   - my ($self, $ssh, $conf, $offset) = @_;
44   - my $deploy_dir = join('/', $conf->{root}, 'releases');
45   - my $current = join('/', $conf->{root}, 'current');
46   - print "[".$ssh->get_host."] running rollback task ...\n";
47   - my @rels = $ssh->capture("ls -1 ".$deploy_dir);
  48 + my ($self, $ssh, $offset) = @_;
  49 +
  50 + $self->log($ssh, "running rollback task ...");
  51 + my $deploy_dir = join('/', $self->config->{root}, 'releases');
  52 + my $current = join('/', $self->config->{root}, 'current');
  53 + my @rels = $ssh->capture("ls -1 " . $deploy_dir);
48 54 @rels = sort(@rels);
49   - my $link = $ssh->capture("ls -l ".$current." | sed 's/^.*->\\s*//'");
  55 + my $link = $ssh->capture("ls -l " . $current . " | sed 's/^.*->\\s*//'");
50 56 my @path = split(/\//, $link);
51 57 my $current_rel = pop(@path);
52 58 my (@past, @future);
53   - foreach my $rel (@rels){
  59 +
  60 + foreach my $rel (@rels) {
54 61 chomp($rel);
55 62 next unless $rel =~ m{^\w};
56   - if($rel == $current_rel){
  63 + if ($rel == $current_rel) {
57 64 push(@future, $rel);
58 65 next;
59 66 }
60   - if(@future){
  67 + if (@future) {
61 68 push(@future, $rel);
62   - } else {
  69 + }
  70 + else {
63 71 push(@past, $rel);
64 72 }
65 73 }
66   - $deploy_dir = join('/', $conf->{root}, pop(@past));
67   - my $log = $ssh->capture("unlink ".$current."; ln -s ".$deploy_dir." ".$current);
68   - $self->logger($ssh, $log);
  74 + $deploy_dir = join('/', $self->config->{root}, pop(@past));
  75 + my $log = $ssh->capture(
  76 + "unlink " . $current . "; ln -s " . $deploy_dir . " " . $current);
  77 + $self->log($ssh, $log);
69 78 return;
70 79 }
71 80
72 81 sub rollback_scm {
73   - my ( $self, $ssh, $conf, $offset ) = @_;
  82 + my ($self, $ssh, $offset) = @_;
74 83
75 84 # load SCM plugin
76   - $self->load_plugin( $self->scm );
  85 + $self->load_plugin($self->scm);
77 86 my $tag = $self->get_last_tag($offset);
78   - print STDERR "Rolling back to tag: $tag\n" if $self->is_debug;
  87 + $self->log($ssh, "Rolling back to tag: $tag") if $self->is_debug;
  88 +
79 89 # TODO change checkout to accept an optional tag so we can reuse it
80 90 # here to check out an old version.
  91 +
81 92 return;
82 93 }
83 94
84 95 sub restart {
85   - my ($self, $ssh, $conf) = @_;
86   - my ( $pty, $pid ) = $ssh->open2pty("sudo ".$conf->{init}." restart");
  96 + my ($self, $ssh) = @_;
  97 +
  98 + $self->log("running restart task ...");
  99 + my ($pty, $pid) =
  100 + $ssh->open2pty("sudo " . $self->config->{init} . " restart");
87 101 my $exp = Expect->init($pty);
88 102 my $ret = $exp->interact();
89   - print "[".$ssh->get_host."] running restart task ...\n";
90   - $self->logger($ssh, "restarted ...");
  103 + $self->log($ssh, "restarted ..." . Dumper($exp));
  104 +
91 105 return;
92 106 }
93 107
94 108 sub checkout {
95   - my ($self, $ssh, $conf) = @_;
96   - print "[".$ssh->get_host."] running checkout task ...\n";
  109 + my ($self, $ssh) = @_;
  110 + $self->log($ssh, "running checkout task ...");
97 111 return;
98 112 }
99 113
100 114 sub cleanup_timestamped {
101   - my ($self, $ssh, $conf, $offset) = @_;
102   - print STDERR "PATH: ".$conf->{root}."\n";
103   - if($conf->{root} =~ m{^.*/\d+$}){
104   - my @path = split(/\//, $conf->{root});
  115 + my ($self, $ssh, $offset) = @_;
  116 +
  117 + $self->log($ssh, "running cleanup task ...");
  118 +
  119 + if ($self->config->{root} =~ m{^.*/\d+$}) {
  120 + my @path = split(/\//, $self->config->{root});
105 121 pop(@path);
106 122 pop(@path);
107   - $conf->{root} = join('/', @path);
  123 + $self->config->{root} = join('/', @path);
108 124 }
109   - print STDERR "PATH2: ".$conf->{root}."\n";
110   - my $deploy_dir = join('/', $conf->{root}, 'releases');
111   - my $current = join('/', $conf->{root}, 'current');
112   - print "[".$ssh->get_host."] running cleanup task ...\n";
113   - my @rels = $ssh->capture("ls -1 ".$deploy_dir);
  125 +
  126 + my $deploy_dir = join('/', $self->config->{root}, 'releases');
  127 + my $current = join('/', $self->config->{root}, 'current');
  128 + my @rels = $ssh->capture("ls -1 " . $deploy_dir);
114 129 @rels = sort(@rels);
115   - my $link = $ssh->capture("ls -l ".$current." | sed 's/^.*->\\s*//'");
  130 + my $link = $ssh->capture("ls -l " . $current . " | sed 's/^.*->\\s*//'");
116 131 my @path = split(/\//, $link);
117 132 my $current_rel = pop(@path);
118 133 my (@past, @future);
119   - foreach my $rel (@rels){
  134 +
  135 + foreach my $rel (@rels) {
120 136 chomp($rel);
121 137 next unless $rel =~ m{^\w};
122   - if($rel == $current_rel){
  138 + if ($rel == $current_rel) {
123 139 push(@future, $rel);
124 140 next;
125 141 }
126   - if(@future){
  142 + if (@future) {
127 143 push(@future, $rel);
128   - } else {
  144 + }
  145 + else {
129 146 push(@past, $rel);
130 147 }
131 148 }
132   - $deploy_dir = join('/', $conf->{root}, pop(@past));
133   - my $num = $conf->{keep_versions} || 5;
  149 + $deploy_dir = join('/', $self->config->{root}, pop(@past));
  150 + my $num = $self->config->{keep_versions} || 5;
134 151 my $log;
135   - while($#past > ($num)){
136   - my $to_del = join('/', $conf->{root}, 'releases', shift(@past));
137   - $log = $ssh->capture("rm -rf ".$to_del);
  152 + while ($#past > ($num)) {
  153 + my $to_del = join('/', $self->config->{root}, 'releases', shift(@past));
  154 + $self->log($ssh, "deleting $to_del");
  155 + $log = $ssh->capture("rm -rf " . $to_del);
138 156 }
139   - $self->logger($ssh, $log);
  157 + $self->log($ssh, $log);
  158 +
140 159 return;
141 160 }
142 161
143 162 sub restart_phased {
144 163 my ($self, $ssh, $conf) = @_;
145   - my ( $pty, $pid ) = $ssh->open2pty("sudo ".$conf->{init}." restart");
146   - my $exp = Expect->init($pty);
147   - $exp->interact();
148   - print "[".$ssh->get_host."] running restart_phased task ...\n";
149   - $self->logger($ssh, "restarted ...");
  164 +
  165 + $self->log($ssh, "running restart_phased task ...");
  166 + unless ($ssh->test("sudo " . $self->config->{init} . " restart")) {
  167 + $self->log(
  168 + 'restart failed: ' . $ssh->error . ' trying stop -> start instead');
  169 + $ssh->test("sudo " . $self->config->{init} . " stop");
  170 + $ssh->test("sudo " . $self->config->{init} . " start")
  171 + or $self->error('restart failed: ' . $ssh->error);
  172 + return;
  173 + }
  174 +
  175 + # my $exp = Expect->init($pty);
  176 + # $exp->interact();
  177 + $self->log($ssh, 'restarted ' . $self->config->{init});
  178 +
150 179 return;
151 180 }
152 181
153 182 sub notify {
154 183 my ($self, $ssh, $conf) = @_;
155   - print "[".$ssh->get_host."] running notify task ...\n";
  184 + $self->log($ssh, "running notify task ...");
156 185 return;
157 186 }
158 187
159   -__PACKAGE__
  188 +__PACKAGE__->meta->make_immutable;

0 comments on commit e1d02fe

Please sign in to comment.
Something went wrong with that request. Please try again.