Friday, December 11, 2009

How I manage my Perl modules on Debian

I just started doing this on another server this morning, and I just realized I can't find my notes on the process! Since I like to record things like this, I started typing and decided I'll turn it into a blog post...

Anyhow, I think I've developed a good enough set of rules and steps for managing perl modules on a Debian-based system that I feel comfortable sharing them with the public. If I'm lucky I will get some useful feedback and critique that will help me further improve!

The basic premise of it this: Try as hard as possible to avoid installing modules from CPAN to the system's perl.

I do this by following these rules-of-thumb:
  • only install system-wide modules from debian packages (excepting local::lib)
  • use local::lib as much as possible
  • properly configure CPAN both system-wide and per-user
So, here's how I set up a fresh system to make following these rules as easy as possible...

Assume starting from a fresh, bare-bones installation of Debian Lenny. This should work with previous releases, but YMMV.

Step 1: Install necessary debian packages to make the cpan client happy.
# Stuff to install for a happy CPAN client:
sudo aptitude install \
  ftp \
  tar \
  curl \
  gzip \
  less \
  lynx \
  wget \
  bzip2 \
  gnupg \
  ncftp \
  patch \
  unzip \
  makepatch \
  libwww-perl \
  libyaml-perl \
  libexpect-perl \
  build-essential \
  libyaml-syck-perl \
  libmodule-signature-perl
Step 2: (optional) Throw your favorite default settings into the system's CPAN config file.

cat <<'END_TXT' >/etc/perl/CPAN/Config.pm
$CPAN::Config = {
    'build_requires_install_policy' => q[ask/yes],
    'check_sigs'           => q[0],
    'build_dir_reuse'      => q[0],
    'prefer_installer'     => q[MB],
    'prerequisites_policy' => q[ask],
    'inactivity_timeout'   => q[300],
    'build_cache'          => q[250],
    'build_dir'         => qq[$ENV{HOME}/.cpan/build],
    'cpan_home'         => qq[$ENV{HOME}/.cpan],
    'histfile'          => qq[$ENV{HOME}/.cpan/histfile],
    'keep_source_where' => qq[$ENV{HOME}/.cpan/sources],
    'prefs_dir'         => qq[$ENV{HOME}/.cpan/prefs],
    'urllist'           => [
        q[http://cpan.mirror.facebook.net/],
        q[http://cpan.yahoo.com/],
        q[http://www.perl.com/CPAN/],
        q[ftp://mirrors2.kernel.org/pub/CPAN/]
    ],
};
1;
END_TXT

Step 3:  Initalize the system CPAN config, just agree to auto-config so it can fill in what's missing.
sudo -H perl -MCPAN -e 'CPAN::Shell->o(qw[conf init])'
Step 4: (optional if you did step 2) Choose and save your default CPAN mirrors.
sudo -H perl -MCPAN -e 'CPAN::Shell->o(qw[conf init urllist]);CPAN::Shell->o(qw[conf commit])';
Step 4:  Install local::lib to the system perl.
sudo -H cpan local::lib
Step 5: (optional) Enable local::lib by default for all users
sudo sh -c 'echo eval \$\(perl -Mlocal::lib\) >> /etc/profile'
Step 6: (optional) Give new users a convenient default config, for example:
cat <<'END_TXT' >/etc/skel/.cpan/CPAN/MyConfig.pm
$CPAN::Config = {
    'prerequisites_policy' => q[follow],
    'tar_verbosity'        => q[none],
    'build_cache'          => q[100],
    'build_dir'         => qq[$ENV{HOME}/.cpan/build],
    'cpan_home'         => qq[$ENV{HOME}/.cpan],
    'histfile'          => qq[$ENV{HOME}/.cpan/histfile],
    'keep_source_where' => qq[$ENV{HOME}/.cpan/sources],
    'prefs_dir'         => qq[$ENV{HOME}/.cpan/prefs],
    # you may not need these, I think a user's CPAN.pm
    # will pick them up from the system CPAN Config.pm
    'urllist' => [
        q[http://cpan.mirror.facebook.net/],
        q[http://cpan.yahoo.com/],
        q[http://www.perl.com/CPAN/],
        q[ftp://mirrors2.kernel.org/pub/CPAN/]
    ],
};
1;
END_TXT

Anyhow, that's a start for now. It sounds like a lot of work now that I've typed it all out, but I really feel like it saves me time and trouble later!