#!/usr/bin/perl # cpanel - installruby Copyright(c) 2011 cPanel, Inc. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cpanel license. Unauthorized copying is prohibited BEGIN { unshift @INC, '/usr/local/cpanel'; } use Cpanel::FileUtils (); use Cpanel::FindBin (); use Cpanel::Logger (); use Cpanel::OSSys (); use Cpanel::SafeRun (); use Cpanel::SysPkgs (); use Cpanel::Tar (); use Cpanel::Update (); use Cpanel::Version::Compare (); # Allow disabling of ruby Cpanel::Update::init_UP_update('ruby'); my %install = ( 'ruby' => '1.8.7-p334', 'rubygems' => '1.3.7', ); my $force = @ARGV && grep( /^--force$/, @ARGV ) ? 1 : 0; my $just_rails = @ARGV && grep( /^--just-rails$/, @ARGV ) ? 1 : 0; my $src_dir = '/usr/local/cpanel/src/3rdparty/ruby'; my $system = Cpanel::OSSys::get_system(); my $prefix = $system eq 'freebsd' ? '/usr/local' : '/usr'; my $gem_bin = -x $prefix . '/bin/gem' ? $prefix . '/bin/gem' : '/usr/bin/gem'; my $ruby_bin = -x $prefix . '/bin/ruby' ? $prefix . '/bin/ruby' : '/usr/bin/ruby'; my $ruby_version_file = '/var/cpanel/version/ruby'; my %archive_types = ( '.tar.gz' => '-z', '.tar.bz2' => '-j', '.tgz' => '-z', ); my $exit_code = system '/usr/local/cpanel/scripts/checkccompiler'; if ($exit_code) { print "C compiler appears to be broken. Ruby cannot be installed until this is resolved!\n"; exit 1; } my $logger = Cpanel::Logger->new(); system '/usr/local/cpanel/scripts/installsqlite3', '--source'; if ( !$just_rails ) { my $needs_gem = -x $gem_bin && !$force ? 0 : 1; if ( !$needs_gem ) { # Gem 0.8.5+ can self update, cPanel started with 1.1 my $gem_version = `$gem_bin -v`; if ( !$gem_version ) { $needs_gem = 1; } else { chomp $gem_version; if ( $gem_version =~ m/^0/ ) { $needs_gem = 1; } } } my $needs_ruby = ( !-e $ruby_version_file || $force ) ? 1 : 0; my $ruby_version = `$ruby_bin -v`; chomp $ruby_version; # check version in file if ( !$needs_ruby ) { if ( !$ruby_version ) { $needs_ruby = 1; } else { if ( open my $vers_fh, '<', $ruby_version_file ) { my $vers = readline $vers_fh; close $vers_fh; chomp $vers; if ( !$vers ) { $needs_ruby = 1; } elsif ( $vers ne $install{'ruby'} ) { my ( $new_version_number, $new_patch_level ) = split( /-/, $install{'ruby'} ); my ( $installed_version_number, $installed_patch_level ) = split( /-/, $vers ); if ( $new_version_number > $installed_version_number ) { $needs_ruby = 1; } elsif ( $new_version_number eq $installed_version_number ) { my ($new_patch) = $new_patch_level =~ m/(\d+)/; my ($installed_patch) = $installed_patch_level =~ m/(\d+)/; if ($new_patch) { # if we distribute a patched version if ( !$installed_patch ) { # they don't have a patched version $needs_ruby = 1; } elsif ( $new_patch > $installed_patch ) { # our patch is greater than theirs $needs_ruby = 1; } } } } } else { $logger->warn("Failed to check version file: $!"); $needs_ruby = 1; } } } if ( $system eq 'freebsd' ) { my @install = ('ruby18'); if ($needs_gem) { push @install, 'ruby-gems'; } my $syspkgs = Cpanel::SysPkgs->new(); if ( !$syspkgs ) { die print "Could not create SysPkgs object\n"; } $syspkgs->ensure( 'pkglist' => \@install ); } else { my $tarcfg = Cpanel::Tar::load_tarcfg(); my @install; if ($needs_ruby) { @install = ('ruby'); } if ($needs_gem) { push @install, 'rubygems'; } INSTALL: foreach my $app (@install) { my $basedir = '/home/cp' . $app . 'build'; eval { system 'rm', '-rf', $basedir; system 'mkdir', $basedir; chdir $basedir or $logger->die("Unable to chdir $basedir: $!"); print "Installing $app version: $install{$app}\n"; my $app_source_base = $app . '-' . $install{$app}; my $app_source; my $decompression_flag; foreach my $archive_extension ( keys %archive_types ) { if ( -e $src_dir . '/' . $app_source_base . $archive_extension ) { $app_source = $app_source_base . $archive_extension; $decompression_flag = $archive_types{$archive_extension}; last; } } if ( !$app_source ) { $logger->warn("Unable to locate source for $app"); die; } system $tarcfg->{'bin'}, '-x', '-p', $tarcfg->{'no_same_owner'}, $decompression_flag, '-C', $basedir, '-f', $src_dir . '/' . $app_source; if ( !-d $basedir . '/' . $app_source_base ) { $logger->warn("Failed to decompress source for $app"); die; } print "Using Dir: $basedir/$app_source_base\n"; if ( !chdir( $basedir . '/' . $app_source_base ) ) { $logger->warn("Unable to chdir to $basedir/$app_source_base failed."); die; } if ( $app ne 'ruby' ) { print "Setting up $app ...\n"; system $ruby_bin, 'setup.rb'; } else { if ($ruby_version) { print "\nUpdating $ruby_version with $install{$app}\n\n"; } # Rubygems installation says you should do this manually???? if ( $app eq 'rubygems' && -e $gem_bin ) { unlink $gem_bin; } unlink $ruby_version_file; my @CONF = ( './configure', '--prefix=' . $prefix, '--enable-shared' ); system @CONF; system 'gmake'; system 'gmake', 'install'; if ( open my $vers_fh, '>', $ruby_version_file ) { print {$vers_fh} $install{$app}; close $vers_fh; } else { $logger->warn("Unable to update version file $ruby_version_file: $!"); die; } } }; print "Removing source directory $basedir\n"; chdir '/'; system 'rm', '-rf', $basedir; } } } $gem_bin = -x '/usr/local/bin/gem' ? '/usr/local/bin/gem' : '/usr/bin/gem'; if ( !-x $gem_bin ) { $logger->warn("gem installation failed. Unable to locate gem binary."); } else { print "gem system update ...\n"; system $prefix . '/bin/gem', 'update', '--system'; print "gem system update complete.\n"; } my $rails_bin = Cpanel::FindBin::findbin('rails'); if ( -x $rails_bin ) { my $rails_version = Cpanel::SafeRun::saferun( 'rails', '--version' ); chomp($rails_version); ($rails_version) = ( split( ' ', $rails_version, 2 ) )[1]; if ( Cpanel::Version::Compare::compare( $rails_version, '>=', '3.0.0' ) ) { my $warning_msg = "\n" . 'Rails 3 has been detected on your system. Rails 3 is not supported at this time.'; if ( -t STDIN ) { print $warning_msg . ' Would you like to remove it and install a supported version of rails? '; my $choice; while ( !defined $choice ) { $choice = ; chomp($choice); if ( $choice =~ /^y(?:es)?$/i ) { $choice = 1; } elsif ( $choice =~ /^n(?:o)?$/ ) { $choice = 0; } else { $choice = undef; } } if ($choice) { uninstallrails3(); } else { exit 1; } } else { print $warning_msg . ' Uninstalling rails 3.' . "\n"; uninstallrails3(); } } } my @rails = ( 'rails', '-v=2.3.14' ); my @install = ( 'mongrel', 'sqlite3' ); my @sqlite3_args = ( '--with-sqlite3-include=/usr/local/include', '--with-sqlite3-lib=/usr/local/lib' ); my $hasperlexpect = 0; eval { require IO::Tty; require Expect; $hasperlexpect = 1; }; print "\nInstalling rails...\n\n"; Cpanel::SafeRun::saferunnoerrordynamic( $gem_bin, 'install', @rails, ); if ($hasperlexpect) { if ( my $pid = fork() ) { waitpid( $pid, 0 ); } else { local $SIG{'ALRM'} = sub { die "Timeout\n"; }; alarm( 20 * 60 ); my $exp = Expect->spawn( $gem_bin, 'install', @install, '--', @sqlite3_args ) or die "Cannot spawn gem installer: $!"; my $expect_pid = $exp->pid(); my $mongrel_number = 0; my $fastthread_number = 0; while ( waitpid( $expect_pid, 1 ) != -1 ) { $exp->expect( 300, [ 'Select which gem', sub { return Expect::exp_continue() } ], [ qr/^\s*\d\.\smongrel\s.*/, sub { if ( $exp->match =~ /\(ruby\)/ ) { if ( !$mongrel_number ) { ($mongrel_number) = $exp->match =~ /\s*(\d+)/; } } else { return Expect::exp_continue(); } } ], [ qr/^\s*\d\.\sfastthread\s.*/, sub { if ( $exp->match =~ /\(ruby\)/ ) { if ( !$fastthread_number ) { ($fastthread_number) = $exp->match =~ /\s*(\d+)/; } } else { return Expect::exp_continue(); } } ], [ '>', sub { my $number = 0; if ($mongrel_number) { $number = $mongrel_number; $mongrel_number = 0; } elsif ($fastthread_number) { $number = $fastthread_number; $fastthread_number = 0; } $exp->send( $number . "\r" ); } ], [ 'timeout', sub { $exp->send("\r"); } ], ); } $exp->soft_close(); exit; } } else { foreach my $app (@install) { system $gem_bin, 'install', $app, '--include-dependencies'; } } if ( !-e '/etc/init.d/ror' && !-e '/usr/local/etc/rc.d/ror.sh' ) { system('/usr/local/cpanel/bin/ror_setup'); } print "Ruby - & - Rails Installed\n"; system '/usr/local/cpanel/scripts/magicloader'; system '/usr/local/cpanel/bin/updatemongrel'; exit; sub uninstallrails3 { Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'rails' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'actionmailer' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'activemodel' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'actionpack' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'activerecord' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'activeresource' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'activesupport' ); Cpanel::SafeRun::saferunnoerrordynamic( 'gem', 'uninstall', '-I', '-x', '-v', '>= 3.0.0', 'railties' ); }