File Coverage

blib/lib/Apache/Voodoo/Install/Distribution.pm
Criterion Covered Total %
statement 24 129 18.6
branch 0 42 0.0
condition 0 18 0.0
subroutine 8 17 47.0
pod 0 8 0.0
total 32 214 14.9


line stmt bran cond sub pod time code
1             ################################################################################
2             #
3             # Apache::Voodoo::Install::Updater
4             #
5             # This package provides the methods that do pre/post/upgrade commands as specified
6             # by the various .xml files in an application.
7             #
8             ################################################################################
9             package Apache::Voodoo::Install::Distribution;
10              
11             $VERSION = "3.0200";
12              
13 1     1   16925 use strict;
  1         3  
  1         40  
14 1     1   7 use warnings;
  1         2  
  1         39  
15              
16 1     1   5 use base("Apache::Voodoo::Install");
  1         3  
  1         109  
17              
18 1     1   17 use Apache::Voodoo::Constants;
  1         2  
  1         29  
19              
20 1     1   6 use File::Spec;
  1         2  
  1         36  
21 1     1   7 use Config::General;
  1         3  
  1         53  
22 1     1   1431 use ExtUtils::Install;
  1         18979  
  1         941  
23              
24             sub new {
25 0     0 0   my $class = shift;
26 0           my %params = @_;
27              
28 0           my $self = {%params};
29              
30 0           $self->{'distribution'} = File::Spec->rel2abs($self->{'distribution'});
31              
32 0 0 0       unless (-e $self->{'distribution'} && -f $self->{'distribution'}) {
33 0           die "ERROR: No such file or directory\n";
34             }
35              
36 0           $self->{'app_name'} = $self->{'distribution'};
37 0           $self->{'app_name'} =~ s/\.tar\.(bz2|gz)$//i;
38 0           $self->{'app_name'} =~ s/-[\d.]*(-beta\d+)?$//;
39 0           $self->{'app_name'} =~ s/.*\///;
40              
41 0 0         unless ($self->{'app_name'} =~ /^[a-z][\w-]*$/i) {
42 0           die "ERROR: Distribution file names must follow the format: AppName-Version.tar.(gz|bz2)\n";
43             }
44              
45 0           my $ac = Apache::Voodoo::Constants->new();
46 0           $self->{'ac'} = $ac;
47              
48 0           $self->{'install_path'} = File::Spec->catfile($ac->install_path(),$self->{'app_name'});
49              
50 0           $self->{'conf_file'} = File::Spec->catfile($self->{'install_path'},$ac->conf_file());
51 0           $self->{'conf_path'} = File::Spec->catfile($self->{'install_path'},$ac->conf_path());
52 0           $self->{'updates_path'} = File::Spec->catfile($self->{'install_path'},$ac->updates_path());
53 0           $self->{'apache_uid'} = $ac->apache_uid();
54 0           $self->{'apache_gid'} = $ac->apache_gid();
55              
56 0           bless $self,$class;
57              
58 0           return $self;
59             }
60              
61             sub app_name {
62 0     0 0   my $self = shift;
63 0 0         $self->{'app_name'} = $_[0] if $_[0];
64 0           return $self->{'app_name'};
65             }
66              
67             sub existing {
68 0     0 0   my $self = shift;
69 0           return $self->{'is_existing'};
70             }
71              
72             ################################################################################
73             # Handles installer cleanup tasks.
74             ################################################################################
75             sub DESTROY {
76 0     0     my $self = shift;
77              
78 0 0         if ($self->{'unpack_dir'}) {
79 0           system("rm", "-rf", $self->{'unpack_dir'});
80             }
81             }
82              
83             sub do_install {
84 0     0 0   my $self = shift;
85              
86 0           $self->unpack_distribution();
87 0           my $new_conf = File::Spec->catfile($self->{'unpack_dir'},$self->{'ac'}->conf_file());
88              
89 0           my $pm_dir = $self->{distribution};
90 0           $pm_dir =~ s/(\.tar(\.gz|\.bz2)?|\.tgz)$//;
91 0           $pm_dir =~ s/^.*\///;
92 0           $pm_dir = File::Spec->catfile($self->{'unpack_dir'},$pm_dir);
93              
94 0 0 0       if (-e $new_conf) {
    0          
95 0           $self->check_existing();
96 0           $self->update_conf_file();
97 0           $self->install_files();
98             }
99             elsif (-e File::Spec->catfile($pm_dir,'Makefile.PL') ||
100             -e File::Spec->catfile($pm_dir,'Build.PL')) {
101              
102 0           $self->info("This appears to be a standard Perl module. Calling CPAN to install it...\n");
103              
104 0           eval {
105 1     1   11 use CPAN;
  1         2  
  1         1279  
106 0           CPAN::Shell->install(File::Spec->catfile($pm_dir,"."));
107             };
108              
109 0           exit;
110             }
111             else {
112 0           print "This distribution doesn't follow a format that I know how to handle. Giving up.\n";
113 0           exit;
114             }
115             }
116              
117             ################################################################################
118             # Unpacks a tar.gz to a temporary directory.
119             # Returns the path to the directory.
120             ################################################################################
121             sub unpack_distribution {
122 0     0 0   my $self = shift;
123              
124 0           my $file = $self->{'distribution'};
125              
126 0           my $unpack_dir = "/tmp/av_unpack_$$";
127              
128 0 0         if (-e $unpack_dir) {
129 0           die "ERROR: $unpack_dir already exists\n";
130             }
131              
132 0 0         mkdir($unpack_dir,0700) || die "Can't create directory $unpack_dir: $!";
133 0 0         chdir($unpack_dir) || die "Can't change to direcotyr $unpack_dir: $!";
134 0           $self->info("- Unpacking distribution to $unpack_dir");
135              
136 0 0         if ($file =~ /\.gz$/) {
137 0 0         system("tar","xzf",$file) && die "Can't unpack $file: $!";
138             }
139             else {
140 0 0         system("tar","xjf",$file) && die "Can't unpack $file: $!";
141             }
142              
143 0           $self->{'unpack_dir'} = $unpack_dir;
144             }
145              
146             ################################################################################
147             # Checks for an existing installation of the app. If it exists, it saves
148             # it's site specific config data, and returns it's version number.
149             ################################################################################
150             sub check_existing {
151 0     0 0   my $self = shift;
152              
153 0           my $conf_file = $self->{'conf_file'};
154              
155 0 0         if (-e $conf_file) {
156 0           $self->{'is_existing'} = 1;
157 0           $self->info("Found one. We will be performing an upgrade");
158              
159 0           my $old_config = Config::General->new($conf_file);
160 0           my %old_cdata = $old_config->getall();
161              
162             # save old (maybe customized?) config variables
163 0           foreach ('session_dir','devel_mode','debug','devel_mode','cookie_name','database') {
164 0           $self->{'old_conf_data'}->{$_} = $old_cdata{$_};
165             }
166              
167 0           my $dbhost = $old_cdata{'database'}->{'connect'};
168 0           my $dbname = $old_cdata{'database'}->{'connect'};
169              
170 0           $dbhost =~ s/.*\bhost=//;
171 0           $dbhost =~ s/[^\w\.-]+.*$//;
172              
173 0           $dbname =~ s/.*\bdatabase=//;
174 0           $dbname =~ s/[^\w\.-]+.*$//;
175              
176 0   0       $self->{'dbhost'} ||= $dbhost;
177 0   0       $self->{'dbname'} ||= $dbname;
178 0   0       $self->{'dbuser'} ||= $old_cdata{'database'}->{'username'};
179 0   0       $self->{'dbpass'} ||= $old_cdata{'database'}->{'password'};
180             }
181             else {
182 0           $self->info("not found. This will be a fresh install.");
183             }
184             }
185              
186             sub update_conf_file {
187 0     0 0   my $self = shift;
188              
189 0           my $new_conf = File::Spec->catfile($self->{'unpack_dir'},$self->{'ac'}->conf_file());
190              
191 0           my $config = Config::General->new($new_conf);
192 0           my %cdata = $config->getall();
193              
194 0           foreach (keys %{$self->{'old_conf_data'}}) {
  0            
195 0           $self->debug("Merging config data: $_");
196 0           $cdata{$_} = $self->{'old_conf_data'}->{$_};
197             }
198              
199 0           $self->debug("Merging database config");
200 0 0         $cdata{'database'}->{'username'} = $self->{'dbuser'} if $self->{'dbuser'};
201 0 0         $cdata{'database'}->{'password'} = $self->{'dbpass'} if $self->{'dbpass'};
202 0 0         $cdata{'database'}->{'connect'} =~ s/\bdatabase=[^;"]+/database=$self->{'dbname'}/ if $self->{'dbname'};
203 0 0         $cdata{'database'}->{'connect'} =~ s/\bhost=[^;"]+/host=$self->{'dbhost'}/ if $self->{'dbhost'};
204              
205 0 0         $self->{'pretend'} || $config->save_file($new_conf,\%cdata);
206             }
207              
208             sub install_files {
209 0     0 0   my $self = shift;
210              
211 0           my $unpack_dir = $self->{'unpack_dir'};
212 0           my $install_path = $self->{'install_path'};
213              
214 0 0         if ($self->{'verbose'} >= 0) {
215 0           $self->mesg("\n* Preparing to install. Press ctrl-c to abort *\n");
216 0           $self->mesg("* Installing in ");
217 0           foreach (5,4,3,2,1) {
218 0           $self->mesg("$_");
219 0 0         $self->{'pretend'} || sleep(1);
220             }
221 0           $self->mesg("\n");
222              
223 0           $self->mesg("- Installing files:");
224             }
225              
226 0 0         $self->{'pretend'} || ExtUtils::Install::install({$unpack_dir => $install_path});
227             }
228              
229             1;
230              
231             ################################################################################
232             # Copyright (c) 2005-2010 Steven Edwards (maverick@smurfbane.org).
233             # All rights reserved.
234             #
235             # You may use and distribute Apache::Voodoo under the terms described in the
236             # LICENSE file include in this package. The summary is it's a legalese version
237             # of the Artistic License :)
238             #
239             ################################################################################