How do I install deps for CPAN module without installing it? - perl

This is a follow-up to my previous question about developing Perl applications. Let’s say I develop an application as a CPAN module using Module::Install. Now I upload the code to the production server, say using a git push, and I would like to install the application dependencies listed in Makefile.PL. If I simply run cpan ., the thing tries to install the application like a regular Perl module, ie. starts to copy the modules and documentation to standard Perl directories all over the system.
Is this the way it’s supposed to be? Do you install the application into the standard Perl directories? I am used to having my Perl applications in one directory with separate lib. Otherwise it seems I’d have to manage a lot of other things, like installing the resources somewhere on path etc. If I just want to install the deps declared in Makefile.PL and run the application tests to make sure everything works, what should I do?
(Is this documented somewhere? I mean, is there something like best practice for deploying and updating non-trivial Perl applications? Or is everybody doing this his own way?)

I might be misunderstanding, but I think what you're looking for is
perl Makefile.PL
make installdeps

If you are using Module::Install, you're really using ExtUtils::MakeMaker behind the scenes. You can use all of the MakeMaker features and the targets it provides. Although the documentation doesn't show every feature, there are some valuable things to be found in the generated Makefile.
However, MakeMaker is old news and most everyone has asked Santa Claus for it to disappear. If you want better control, including creating your own targets and process, Module::Build is orders of magnitude easier to work with as well as cross-platform (even if that just means not using a different make, gmake, or whatever on the same OS on different boxes). If you deviate from the normal, consumer-grade installation process, you're life will be easier without MakeMaker.
Some people appreciate the brevity of the Module::Install build file, but once constructed, you don't spend a lot of time messing with your build file so it's not that much of a real benefit. When the little benefit you get locks you into MakeMaker, it's not a win at all.
A 2014 update: Module::Build has now fallen out of favor and needs a maintainer. It never quite got to the point where people could use it to build and distribute XS modules. It was deprecated in Perl v5.19 although you can still get it from CPAN.

You could look at Module::ScanDeps to generate a list of dependent modules for installing. Or Par::Packer for packaging up the whole thing as an "app".

Related

Perl module installation structure and version control

I am just starting to organize some stuff on the cluster and would like some advice on it. I posted a recent question How to organize Perl modules and got some good answers about what I was doing incorrectly. I was trying to install each perl module independently by setting the PREFIX for Makefile.PL each time to /path/to/lib/module-name/module-version/installation happens here.
For e.g. for a module JSON, I installed it like this:
perl Makefile.PL --PREFIX=/path/to/lib/perl5/5.22.1/JSON/2.53
make
make test
make install
For module Data-UUID, I did it like this:
perl Makefile.PL --PREFIX=/path/to/lib/perl5/5.22.1/Data-UUID/1.221
make
make test
make install
So it made a directory JSON/2.53 in /path/to/lib/perl5/5.22.1 and that's where it installed the package. But because I change the PREFIX for each individual module, I have to set the PATH in the bash_profile accordingly, which is kind of messy.
My main goal to do this was for version control. In a hypothetical scenario where different versions work for two of your teammates, say JSON/2.52 works for X and JSON/2.53 works for Y, how do you control for versions without having to ask them to install their versions locally? In another scenario, what if a version worked for you 3 months back and the updated version doesn't work for you anymore? How do you keep track of versions if you install everything in one directory?
I also have more questions on the module local::lib but I will post it as another question.
Thanks!
Maintaining concurrent versions of CPAN modules is asking for grief. I would suggest instead - don't, use docker for anything that's got any sort of deployment. That way you can have local installation of stuff + deps in an isolated container.
It's a bit like early days yet on docker, but they're a significant amount of enthusiasm and support for it from some very big names.
Personally I'm just using it to bundle up "mojolicious" perl webapps behind a reverse proxy, and maintain their dependencies as a self contained installation (which I can run/test/deploy autonomously)

Bundling up a perl script with its dependencies?

I have a perl script that I've put together to do some monitoring and graphing.
It works nicely on my dev system, where I have carte-blanch to install my own modules from CPAN.
What I'm looking at doing is bundling it up to deploy onto another system. But here's the catch - this other system is 'standalone' and has no network connection. (And I have change control paperwork to fill in, indicating what I'm installing).
As a result, I'd really like a nice easy way to figure out:
- What modules my scripts are making use of. (Including dependencies)
- how to easily grab them (cpan get probably)
- Is there an easy way to tell what external binaries I'm using? (I'm using for sure ssh and rrdtool - the former is definitely installed, the latter probably not).
I have a few thoughts on how to do this, but it strikes me as something that should be smoother.
I may also need to deploy a new perl, so I'm pondering whether I'm better off 'installing' the modules with system perl (probably 5.8.8 on RHEL5), or just 'packaging' the whole thing in a directory of it's own with a standalone perl instance.
Use pp to package your script and all dependant modules and libraries into a stand alone executable.
pp -x yourscript.pl -o outputfilename
See the documentation for examples of how to link to external shared objects (etc) if required. With pp you don't need perl on the target system where outputfilename will run.
Revisiting this, as the need hasn't really gone away. I have moved towards using docker - this is an 'image' and 'container' system for app deployment, which amongst other things, allows you to 'package' an application.
You create a Dockerfile - which is analagous to a Makefile - that runs through the steps to install perl + dependencies (either via a package manager, or from CPAN).
Once it has, you have a self contained, runnable 'image' that you can clone and create an instance of (a "container" in docker parlance).
It's also quite useful - even if you don't then deploy via container - to figure out what the dependencies of this application/packages were. The version in the container has everything locally installed that it needed, because it was a clean build.
When you have a system where you can't control the Perl installation (and the install is a really, really old version of Perl like 5.8.8 which is missing many nice improvements like state variables, autodie, say, and switch), you should look into Perlbrew.
Perlbrew allows you to install a user version of Perl. (In fact, it allows you to install multiple versions of Perl), and allows you to switch between the Perlbrew install and the officially installed version. It makes doing everything in Perl much, much easier.
You will have freer access to install new Perl modules, and you can do that task yourself rather than wait for your IT department to do it for you.
I ended up using it on one of our systems where the primitive version of Perl just wasn't doing what my version of Perl did. I originally asked our IT to upgrade, but they really messed up the upgrade. After going back and forth, I simply asked if I could install Perlbrew.
Which is an important point. Always ask permission. A lot of time, the IT department is more than happy to oblige. They're not Perl people, and CPAN is a world they don't want to deal with. Being able to get out of having to answer your beck and call about installing this or that Perl module is a great relief.

Setting up a common perl/cpan environment

so I'm having a lot of fun with Perl at home for some time now.
How much more difficult do things get when you develop Perl modules (In my case it's mostly catalyst) in a team? How do we make sure we all got the same development environment (Perl/Module versions)? Simply by keeping up to date with CPAN? Do some teams setup their 'private' CPANs?
Using the following things should make your life easier.
check out local::lib you could easily then create a server that each member could sync these modules too.
You probably don't really want to mirror all of cpan. just the most recent modules which is why you'd use minicpan.
If you're using recommended modules in Task::Kensho then using the latest releases shouldn't be a problem as they should be surprisingly changing API on you. Basically by doing this you make sure you don't end up with your team reinventing the wheel or hopefully using 3 different modules that do the same thing.
And you want to make sure that your team uses good Perl coding practices and not the bad ones. There are a lot of bad ones. Read Perl Best Practices, remember it's just a guideline you should tune it too your team and your style.
local::lib
minicpan
Task::Kensho
Perl Best Practices
It is not exactly clear what is meant by "in a team".
If the team is at some company, the best solution is of course a shared directory where only the CPAN modules you need are installed.
If the team is a bunch of guys working collaboratively from their home computers, there are a couple of solutions.
One that comes to mind is as follows:
Have a shared "latest version of module to install" list in a file, accessible publicly from the web (on someone's home page, your favorite source control system, Google docs, whatever).
Write a little Perl script which retrieves that file from the web or checks it out of repository, loops over each CPAN module listed in the file, and verifies that locally installed version is the correct one. If upgrade is needed, have the script install update from CPAN.
Have that script run as a scheduled job (cron on Unix, or at/scheduler on Windows) as admin/root account, or at least account which has enough perms to install CPAN modules.
I won't provide details of script implementation, because I don't even know if this is for Windows or Unix, and doing all those tasks are fairly routine Perl coding - if you get stuck, you are always welcome to ask follow up questions on SO! :)

What concerns should I have when installing additional Perl modules on a server?

I would like to ask my system administrator to install various Perl modules such as Moose and Data::Alias. The system is Red Hat Enterprise Linux 5, running Perl 5.8.8. The only problem that I can think of is that some already-installed modules might need to be upgraded and thus run the risk of breaking something. What else should I be concerned about?
I do not know your company's policy, but it would probably be a better idea not to mess with your system perl and install the additional libraries and their prerequisites (and even a dedicated perl) in a different location and use lib.
See also How do I keep my own module/library directory? in perlfaq.
Our systems administrators are the ones who are concerned with making sure requested Perl modules don't break anything else on their systems.
So we ask, then they can say "No, that will break X, please install that in user-space." or "We'll install that at non-standard location Y, for compatibility reasons." I don't know all of the things they take into consideration when making that decision. The only thing I am supposed to know is whether or not my applications will break when modules are installed/updated.
If your system administrators are passing this responsibility (i.e. knowing the impact on the system as a whole) to you as a developer, it's probably much safer to go along with Sinan's suggestion and install the modules you need in a non-standard location for yourself. Having to be a system administrator and a developer at the same time while being paid to be only one is no fun.
The trick is to not get rid of your old setup until you know your new setup works. The rub is that the CPAN toolchain doesn't care and will happily install new files over old ones without giving you a way to uninstall your damage.
If I'm working on a big project where I'm going to upgrade modules, I like to put the new modules in their own, new directory. I can test things by settingPERL5LIB to the new directories, and if it doesn't work out, I'm back to the old setup with a simple change of the environment.
Some people do something similar with source control. They put their modules directory in a versioning system. When they install new modules, they check in the source. When something breaks, they just roll back the changes. They can also tag versions so they can roll back to any working point.
This is an often asked question especially if you are using shared hosting or have a hosting provider that is leery of installing perl modules.
There is a fix, a way to work around this problem of mixing system modules and your own modules, and that fix is called local::lib. local::lib provides a way for you to install modules locally, in a library specified by you, which you have control over. You can use /home/you/perl5/ for example, or any path you think will work.
PS - Moose modules will most likely not interfere with other perl 5 modules since Moose has clean and separate namespace. It does require lots of modules from CPAN however, so warn your sysadmin in advance. :)
Also, ask your sysadmin to upgrade perl to 5.10, that brings lots of good new stuff into perl's core and allows you to use some shiny new perl technology.

What's the best system for installing a Perl web app?

It seems that most of the installers for Perl are centered around installing Perl modules, not applications. Things like ExtUtils::MakeMaker and Module::Build are very well suited for modules, but require some additional work for Web Apps.
Ideally it would be nice to be able to do the following after checking out the source from the repository:
Have missing dependencies detected
Download and install dependencies from CPAN
Run a command to "Build" the source into a final state (perform any source parsing or configuration necessary for the local environment).
Run a command to install the built files into the appropriate locations. Not only the perl modules, but also things like template (.tt) files, and CGI scripts, JS and image files that should be web-accessible.
Make sure proper permissions are set on installed files (and SELinux context if necessary).
Right now we have a system based on Module::Build that does most of this. The work was done by done by my co-worker who was learning to use Module::Build at the time, and we'd like some advice on generalizing our solution, since it's fairly app-specific right now. In particular, our system requires us to install dependencies by hand (although it does detect them).
Is there any particular system you've used that's been particularly successful? Do you have to write an installer based on Module::Build or ExtUtils::MakeMaker that's particular to your application, or is something more general available?
EDIT: To answer brian's questions below:
We can log into the machines
We do not have root access to the machines
The machines are all (ostensibly) identical builds of RHEL5 with SELinux enabled
Currently, the people installing the machines are only programmers from our group, and our source is not available to the general public. However, it's conceivable our source could eventually be installed on someone else's machines in our organization, to be installed by their programmers or systems people.
We install by checking out from the repository, though we'd like to have the option of using a distributed archive (see above).
The answer suggesting RPM is definitely a good one. Using your system's package manager can definitely make your life easier. However, it might mean you also need to package up a bunch of other Perl modules.
You might also take a look at Shipwright. This is a Perl-based tool for packaging up an app and all its Perl module dependencies. It's early days yet, but it looks promising.
As far as installing dependencies, it wouldn't be hard to simply package up a bunch of tarballs and then have you Module::Build-based solution install them. You should take a look at pip, which makes installing a module from a tarball quite trivial. You could package this with your code base and simply call it from your own installer to handle the deps.
I question whether relying on CPAN is a good idea. The CPAN shell always fetches the latest version of a distro, rather than a specific version. If you're interested in ensuring repeatable installs, it's not the right tool.
What are your limitations for installing web apps? Can you log into the machine? Are all of the machines running the same thing? Are the people installing the web apps co-workers or random people from the general public? Are the people installing this sysadmins, programmers, web managers, or something else? Do you install by distributed an archive or checking out from source control?
For most of my stuff, which involves sysadmins familiar with Perl installing in control environments, I just use MakeMaker. It's easy to get it to do all the things you listed if you know a little about MakeMaker. If you want to know more about that, ask a another question. ;) Module::Build is just as easy, though, and the way to go if you don't already like using MakeMaker.
Module::Build would be a good way to go to handle lots of different situations if the people are moderately clueful about the command line and installing software. You'll have a lot of flexibility with Module::Build, but also a bit more work. And, the cpan tool (which comes with Perl), can install from the current directory and handle dependencies for you. Just tell it to install the current directory:
$ cpan .
If you only have to install on a single platorm, you'll probably have an easier time making a package in the native format. You could even have Module::Build make that package for you so the developers have the flexibility of Module::Build, but the installers have the ease of the native process. Sticking with Module::Build also means that you could create different packages for different platforms from a single build tool.
If the people installing the web application really have no idea about command lines, CPAN, and other things, you'll probably want to use a packager and installer that doesn't scare them or make them think about what is going on, and can accurately report problems to you automatically.
As Dave points out, using a real CPAN mirror always gets you the latest version of a module, but you can also make your own "fake" CPAN mirror with exactly the distributions you want and have the normal CPAN tools install from that. For our customers, we make "CPAN on a CD" (although thumb drives are good now too). With a simple "run me" script everything gets installed in exactly the versions they need. See, for instance, my Making my own CPAN talk if you're interested in that. Again, consider the audience when you think about that. It's not something you'd hand to the general public.
Good luck, :)
I'd recommend seriously considering a package system such as RPM to do this. Even if you're running on Windows I'd consider RPM and cygwin to do the installation. You could even set up a yum or apt repository to deliver the packages to remote systems.
If you're looking for a general installer for customers running any number of OSes and distros, then the problem becomes much harder.
Take a look at PAR.
Jonathan Rockway as a small section on using this with Catalyst in his book.