Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a Perl application that needs a lot of dependencies that i need to deploy on numerous servers

I would like to make a script that installs that Perl application automatically and quickly.

To be faster, i want to install most of my dependencies using my package manager instead of installing them with CPAN

Is there a way to determine automatically from a list of perl modules if there is a debian package for it? And if there is one, install the package, if not install the Perl module from CPAN ?

share|improve this question
    
Did you try cpan's tools? What have you tried? –  F. Hauri Jan 2 '13 at 16:43
    
For now, I use cpan to install all the modules, but I would prefer to install the packages if they exists (faster, perfectly integrated to my system) –  Vincent Membré Jan 2 '13 at 16:51
    
To be faster, is use cpanm, but it's still not as fast as the packages –  Vincent Membré Jan 2 '13 at 16:52
    
Hem... And what's your system? –  F. Hauri Jan 2 '13 at 16:58
    
debian Squeeze for the most part of them –  Vincent Membré Jan 2 '13 at 17:00
show 1 more comment

3 Answers

Hmm, One way would be to look at writing a wrapper around the systems package manager, i.e. apt-get, and if packages not returned then install with cpan, cpanm, etc.

sub check_pre_req_package {
  my $package = shift;
  system("dpkg -s $package > /dev/null 2>&1");
  if ( $? != 0 ) {
    system("apt-get -y install $package > /dev/null 2>&1");
      if ( $? != 0 ) {
        system("cpanm $package");
      }
  }
  elsif ($? == 0) {
    print "Package $package is already installed \n";
  }
}

my @pre_req_packages = qw(strace nmap gcc);

foreach(@pre_req_packages) {
  check_pre_req_package($_);
}

Of course with that way you'd have to be case sensitive (or change the case) as I believe that debian uses a format of lib(package-name)-perl in all lower case and cpan will want a different format, etc, plus this code is untested and something that just thrown together.

Then there's good old bash scripting, as hell I used system commands in this example

My best suggestion is that you look into using something like cfengine or puppet and/or some other I'm sure is out there system configuration management. Then use svn or git or so... to make changes to push to a repo that will deploy to all your servers. If your going to be managing and making the changes to "numerous" servers then cfengine/puppet/etc will make your life a lot easier once set up. just my two.

share|improve this answer
add comment

My suggest:

  • First, take a look on .bash_history on target already installed, there is a great chance you will find a lot of already writted lines, ready to use, of your script to install a Perl application and its dependencies automatically

    Than you could install one target, using only one terminal (care not to use another session on same target for ensuring that every actions will correctly logged), and using script command.

    script -t install-perl 2>install-perl.t

    Try to not use interactive commands, or log each action to another text file in your desk.

    From there, you must be able to retrace finely the whole process

    scriptreplay install-perl.t install-perl

    and to build a shell script, even by filtering the result file install-perl or simply the target's .bash_history.

  • Intermediate way Make one correct installation, than replicate them using tar. Sometime it's simplier to act so as all not debian packaged adds are confined in /usr/local.

    Or even simplier, having /usr/local on separated partition shared and mounted in read-only mode on all targets.

  • Finaly, more Debian: From that correct installation, (could be called master), create a debian package, install them in your own enterprise repository (simple directory in some internal web or ftp server, containing exact directory structure and a public key your have to do.). Reference this reposit in your targets and maintain your master correctly.

    Nota: Idealy you have to build one package per perl library you use (or one per familly of libraries), but this could generate some extra work and is not really needed unless you want to share or contrib with Debian packagers.

Nota: This last solution look a little overkill (implie some learning for maintener), but in fine:

  1. this as to be learned one time only and is very quick after second, maybe third upgrade.
  2. this is the most efficient and scalable solution.
  3. this have to be done on already existant work without having to tinking about again.
  4. if well done, this could exist longer than the hardware for which all this is done.
share|improve this answer
add comment

Might I suggest using perlbrew. In general I've found over the years that if you have an application that depends on a particular interpreter: Ruby, Perl, Python, etc. It's usually a better idea to setup a dedicated installation of the interpreter for your application rather than rely on the ones included in a particular distro.

Perlbrew maintains an entire installation of Perl in your $HOME directory. In fact you can have multiple versions of Perl along with its libraries so that you can perform testing, before you fully upgrade from one version to the next. By doing it this way your application is completely separated from upgrades that may occur when relying on your distro's version of Perl.

Excerpt from the perlbrew webpage:

perlbrew is a tool to manage multiple perl installations in your $HOME directory. They are completely isolated perl universes. This approach has many benefits:

  • No need to run sudo to install CPAN modules, any more.
  • Try the monthly released new perls.
  • Learn new language features.
  • Test your production code against different perl versions.
  • Leave vendor perl (the one that comes with OS) alone.

Installation is a breeze

curl -kL http://install.perlbrew.pl | bash

Usage

# Pick a preferred CPAN mirror
% perlbrew mirror

# See what is available
% perlbrew available

# See full help
% perlbrew help

# Install some Perls
% perlbrew install 5.14.0
% perlbrew install perl-5.8.1
% perlbrew install perl-5.13.6

# See what were installed
% perlbrew list

# Switch perl in the $PATH
% perlbrew switch perl-5.12.2
% perl -v

# Temporarily use another version only in current shell.
% perlbrew use perl-5.8.1
% perl -v

Resources

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.