Is it possible to install perl prerequisites before distribution testing and how? - perl

I try to build a Perl distribution for a home-made module, from the Module::Starter base. Every test pass on my machine, but when I upload it to CPAN to get some more universal tests from cpantesters.org, some test failed on other architectures or OS, but I can't understand why. I can see in test reports that some of my prerequisites are not installed before testing but I would like it to.
I've tried to list these dependencies into the Makefile.PL PREREQ_PM hash and then in the TEST_REQUIRES hash, but it didn't changed a lot of results.
Then, when I've removed the dependencies from my local machine and tried to install my module using Cpanm, it downloads dependencies first, test passed and install has been a success.
This is my first try for a module, so I think I am missing something, maybe I am too used of the Cpanm magic. Thanks for any help.

The problem is something different. Andreas' smoker very probably built the dependency App::Ack (which looks in the fail reports like being absent) successfully. But here come at least two problems:
When a distribution gets tested, then its dependencies may or may not be installed already. However, it's guaranteed that all dependent modules are made available through the PERL5LIB environment variable, so make test usually works (To be more specific, if the install Module command is used in the CPAN shell, then all dependencies are installed immediately. If the test Module command is used, then dependencies are only built, but not installed. The CPAN user can do the installation later using install_tested). So it may be that App::Ack is not installed here, just built. Especially this means that the ack script is not installed in the final location.
Even if it is installed, many smoke testers or users who have multiple perls installed in parallel use a non-standard directory for this perl. So ack wouldn't be installed in /usr/bin or /usr/local/bin, but in the bin directory belonging to this perl. This directory may or may not be in the user's PATH at all. So you cannot assume that can_run("ack") works here. A workaround here is to add $Config{scriptdir} temporarily to $ENV{PATH}. Another solution would be to use the App module instead of the script, if it's possible. Unfortunately it looks like ack can only be called as a script.
If you look at a sample fail report, then you can see that App::Ack was installed (it appears in the PREREQUISITES section both under requires and build_requires, you can also see which App::Ack version is installed in the "HAVE" column). You can also see the user's PATH (in the ENVIRONMENT section). And you may guess about the scriptdir for this perl, it's usually the same directory where the perl binary itself is installed, and the path to current perl is visible in $^X (under "Perl special variables").
If you want to reproduce the behavior, then you need to deinstall ack from your machine, build a custom perl using ./configure.gnu --prefix=/path/to/custom/perl-5.X.Y, and use this perl for tests.

Related

Installing an perl based web-app in extremely restricted environment

Because i have a long series of comments with #ikegami, I cleaning up the question, in a hope it will be more understandable. Unfortunately, english isn't my "main" language. :(
Let say, having an environment where:
no development tools are installed (no make, nor gcc or like)
perl is installed with its core packages, nothing more
no outgoing network access is allowed - e.g. the user couldn't use curl nor cpan to download/install perl dependencies
the user even doesn't have admin (root) rights
but want install and evaluate some perl based web-app, let call it as MyApp
The MyApp
doesn't uses any XS-based module. (at least, I hope - in the development me using plenv and cpanm, so never checked the installed dependencies in depth)
it is an pure PSGI app, the simple plackup app.psgi works OK
the app uses some data-files which should be included in the "deployment".
The main question is: how to prepare the MyApp, and the all used CPAN-modules, to be easily installed in such restricted environment?
The goal is:
i don't need save my efforts and my time
but i want save the user's time and want minimize the needed actions on his side, so the installation (deployment) should be simple-as-possible.
E.g. how to get an running web-app to the user's machine with minimum possible (his) steps.
- the simplest thing is could be something as:
- copy one file (zip, or tarbal)
- unpack it
- from the terminal execute some run.pl in the unpacked directory.
To get the above simple installation, my idea was the following:
1.) Create an tarball, and after the unpacking will contain 3 folders and 1 perl-script, let say:
myapp_repo/
myapp_repo/distlib #will contain all MyApp's perl modules also ALL used CPAN modules and their dependecies
myapp_repo/datafiles #will contain app-specific data files and such
myapp_repo/install.pl
myall_repo/lib #will contain modules directly used by the `install.pl`
2.) I will develop an install.pl script, and it will be used as the installer-tool, like
perl install.pl new /path/to/app_root
and it will (should):
create the all needed directories under the /path/to/app_root (especially the lib where the will install the perl modules)
will call "local" cpanm internally (from the myapp_repo/lib) to install the app's perl modules and their CPAN dependencies using only distribution files from the distlib.
will generate and install the needed runtime script and the app.psgi into the /path/to/app_root/bin
will install the needed data-files for the app.
3.) So, after this the user should be able to simply run:
/path/to/app_root/bin/plackup /path/to/app_root/bin/app.psgi
In short, the user should use:
the system-wide perl and the system-wide perl-core modules
and any other
runtime perl-scripts (like plackup)
and the required CPAN-modules
should be installed to an self-contained directory tree using only files (no net-access).
E.g. the install.pl should somewhat call internally the cpanm to achieve (as equivalent) for the following cpanm command
cpanm --mirror file://path/to/myapp_repo/distlib --mirror-only My::App
which, should install My::App and all dependencies without network access using only the files from the myapp_repo/distlib
Some questions:
Is possible to use cpanm (called as an locally installed module) without the make?
For creating the myapp_repo/distlib, me thinking about using Pinto. Is it the right tool for achieve the above?
forgot me something? or with other words:
Is the above an viable (read: working) way?
are are any other tools, which i could/should to use for simplifying the creation of such distribution tarball?
#ikegami suggesting some method:
- "install everything" in one fresh-directory on my machine
- transfer this self-contained directory to the target machine
It sound very good, because this directory could contain all the needed app-specific data-files too, unfortunately, I don't understand the details how his solution should be done.
The FatPacked solution looks interesting too - need learn about it.
Don't write your own make or installer. Just copy it make from a different machine (which is basically what apt/yum/etc do anyway, and which you'd have to do even if you wrote your own). You'd be able to use cpan in 5 minutes!
Also, that should allow you to install gcc if you need it (e.g. to install an XS module), although it doesn't sound like you do. If you do install gcc, I'd install my own perl to avoid having to deal with PERL5LIB.
Tools such as minicpan will allow you to install any module from CPAN without internet access. Of course, you can keep using the command you are already using it if mirrors the packages you need.
The above explains how to simply and quickly setup a machine so it can use cpan and thus install any module easily.
If you just want to install a specific module and its dependencies, you can completely avoid using cpan on the target machine. First, you need a fresh install of Perl (preferable of the same version as the one on the target system). Then, simply install the module to a fresh dir on your machine, and transfer that dir to the target machine. That's it; nothing else needs to be done. This even works for XS modules if the two machine are similar enough.
This is what ppm (ActiveState's Perl package manager) does.
Unfortunately, while this solution is almost as simple as the one above, it's not nearly as flexible, it doesn't run the test suite of the modules being installed, etc. It does have the advantage of not requiring the transfer of any binary (if you're not installing any XS modules).

What is difference between installing a perl module and copying whole folder?

I have installed a perl module, say XYZ then a folder is created that contains many .pm files. I copied the folder and put it in any other system where XYZ is not installed. So, I'm able to use methods of XYZ module in both system. I mean, I'm unable to find out the difference between these method, but I think there must be some. What I know is, when we install a perl module then dependencies also gets installed. Am I right? Can anyone mention other difference between two, if any?
A few off the top of my head:
In case of an XS module, the code is compiled for the local platform.
Installing a module via cpan usually runs the test suite so if there is any other reason beyond dependencies why it wouldn't work, you're told so (I guess that's very rare though)
Regular installation automatically goes to a directory where your perl can find modules.
Of course you can take care of all these yourself. These days chances are pretty good you're running either Linux or Windows on something x86-ish and as long as you only copy Linux to Linux and Windows to Windows, and to the same place as on the source system, you'll be fine. Basically that's what binary Linux distributions and ActivePerl packages do, too, and it may make sense e.g. if you want to avoid installing a whole bunch of compile-time dependencies on all target systems. Just make sure you don't get yourself into a mess by writing to system directories (e.g. /usr/share/perl5) that are supposed to be managed by your system's package manager.

Perl module version

I have a couple of perl modules installed in the $HOME of my web server. The web server used to run perl 5.8.8 so they were installed under $HOME/perl/lib/perl5/5.8.8/...
During a server migration, the web hosting company changed perl to 5.10.1 but I did not know about this until my scripts started failing. I managed to do a quick dirty fix by copying the 5.8.8 tree to 5.10.1 and it seems to work OK now, but I want to avoid my scripts failing like this in future.
What is the best way of allowing my scripts to use the locally stored modules under the 5.8.8 folder even if the perl version gets upgraded again?
I can add a check for the expected perl version in my scripts and email myself if it changes, but it's too late by then as the script may have failed several times before I can fix the problem. Ideally I want to prevent the scripts failing at all.
Depending on the amount of flexibility you have when configuring your environment you may want to use Perlbrew.
to maintain an independent Perl installation at a specific version. This can avoid nasty surprises when the system-wide Perl installation changes.
The thing you really should do is ensure that your needed modules are installed in the new installation. Especially for XS (C-level) modules there is no guarantee that they will run on a new version of Perl without recompiling since the core may have changed.
You should make a Makefile.PL or Build.PL which declares the dependencies of your scripts and you company should make it a policy to execute those scripts on server migration.
Finally, yes you can check $^V which is the running Perl. And if you do it inside a BEGIN block it will be executed during startup. In fact you can use local directories for your (pure perl) modules and then point to them using the lib module.
Why did you move the files at all? Just keep add to PERL5LIB instead.
PERL5LIB=$HOME/perl/lib/perl5/5.10.1:$HOME/perl/lib/perl5/5.8.8
I strongly recommend that you simply use perlbrew to install a build of Perl in your home directory instead of being at your host's mercy.

Is it safe to have various Perl installations on one machine share a cpan_home?

I have a dated system perl 5.8.8 on a Linux machine and installed a 5.12.4 from ActiveState. Both perl's cpan_home is ~root/.cpan. I was about to change the new perl's cpan_home, but then I realized I didn't know whether I really have to do this or whether it would just result in multiple copies of modules being downloaded to different directories when in fact they could be shared.
So can they? Is it safe? With regard to compiling? Or do I have to go for separate cpan_home directories?
Note that I tried perlbrew first but it failed with Can't load '../lib/auto/IO/IO.so' for module IO: ../lib/auto/IO/IO.so: wrong ELF class: ELFCLASS64 at ../lib/XSLoader.pm line 70. So instead of pursueing the issue I went for ActivePerl, which installs easily.
I have a dozen builds of Perl on my system, and they all use ~/.cpan. I have never had a problems, but I cannot say that it is safe. It depends on the settings therein. Specifically,
build_dir_reuse should (probably) be zero.
makepl_arg shouldn't contain INSTALL_BASE.
mbuildpl_arg shouldn't contain --install_base.
"Install base" overrides where the modules are installed. If you start installing the modules for all your builds in one location, you will have problems due to incompatibilities between versions, releases and builds of Perl.
If you want to share .cpan and have a local install directory, you can probably get away with using PREFIX=/home/username/perl5 LIB=/home/username/perl5/lib instead of INSTALL_BASE=/home/username/perl5. It uses a smarter directory structure.
By the way, local::lib causes "install base" to be used, so you'll run into problems if you use local::lib with multiple installs of Perl.

How do I install Perl modules on machines without an Internet connection?

I need to install my Perl-based software on networked machines which aren't connected to the internet. Therefore, I would like to download specific versions and/or latest versions of the Perl modules and I would also like to know if there is an install procedure required for these modules.
Background:
The machines aren't connected to the internet for security reasons and its deemed unnecessary also.
I would place the downloaded modules on a machine that I call the 'install server' and it contains my Perl based software and would also contain the local copies of the Perl modules.
I call a machine that I want to install my Perl-based software on, the 'target machine', also not connected to the internet. There can be several target machines, each can run this software that I want to install. I log onto the target machine and run an install script which would connect to the install machine via the local network to obtain the Perl-based software and dependent Perl modules and installs them.
So I need to know:
How/Where to get specific versions of Perl modules, e.g. CGI.pm etc
How to install these Perl modules. Is it a case of just placing them in a directory somewhere, e.g. a library path and making sure that this directory path is in the #INC library path environmental variable, if it is not already?
I would prefer not to have to do anything like make install etc. as part of installing the modules. I would like to modules to be pre-compiled or prepared as necessary so it is as simple as possible to install them. I want to avoid additional dependencies like make and its configuration, and having to parse its output to check whether it was successful.
Please help me by asking the above specific questions as I am not able to change the concept of 'install machine' and 'target machine' which aren't connected to the internet - I have to provide a solution that works within this arrangement.
The usual way to solve "I want to install stuff from CPAN but without network" problems is to use a minicpan as David Dorward wrote in his answer. But since you're going one step further, saying that you'd rather not do any real installation on the client (target) machines at all, and that you want to use precompiled modules if possible, I urge you to check out PAR and specifically PAR::Repository (server) and PAR::Repository::Client.
Since this approach needs some research before you're up to speed, I wouldn't suggest it for "I just need Foo.pm" like problems. Once you're talking about a handful of dependencies and at least a handful of clients, then it becomes a more appropriate solution.
For an outline of how it works, check out the slides of my talk at YAPC::EU 2008. It also hints at solutions to the bootstrapping problem of making the PAR::Repository::Client module available on the clients (hint: PAR can generate self-contained executables).
You can create a MiniCPAN that has just the latest versions of everything from CPAN. You can insert additional, non-public modules into it with CPAN::Mini::Inject. If you need to greater control over versions (i.e. not choosing the latest versions), you might want to create a DPAN.
With any of these solutions, you can configure your CPAN client to pull from your local source. That could be a directory you know ahead of time or something that you figure out dynamically, like a CD or a thumb-drive. It's just a matter of setting up the configuration correctly.
You might be able to get away with creating operating-system packages for most of your work, but that still means you have to compile them at least the first time.
1) How/Where to get specific versions of Perl modules, e.g. CGI.pm etc
http://search.cpan.org/
If you don't want the latest version, you can get an earlier version by following the link in the breadcrumbs.
http://img.skitch.com/20091209-bu7kt3bj65374k7iijfnhrue2y.png
2) How to install these Perl modules. Is it a case of just placing them
in a directory somewhere, e.g. a library path and making sure that this
directory path is in the #INC library path environmental variable, if
it is not already?
That sometimes work, but you really should go through the perl Makefile.PL && make && make test && make install process.
Doing this would require that you manually chase all the dependencies though. You would probably be better off with something like minicpan.