How can I safely clean up root's .cpan folder? - perl

I have a development class Linux server which has been used for a great deal of Perl code creation and testing. On this machine is a /root folder, part of the / partition, and in there is a .cpan folder - which is currently consuming almost 1TB of disk space. We have been having issues with free space on the / partition and I'd like to 'clean up' this .cpan folder. The build sub-directory has 100's of sub-folders, which appear to be already installed CPAN modules. Is it safe to delete those? Is there an option/command I can use inside of cpan to check or assist in the clean up?
I've checked several man pages and on-line searches, but I'm not certain what could be removed without impacting the system. Are there setting I could change that would keep this folder clean in the future?
Thanks.

Short answer: Yes, you can delete that ~root/.cpan/build folder without affecting your system.
On the other hand: It's not recommended that user root has a .cpan folder at all. Usually you would install modules as some other (non-root) user. cpan then complains about not being able to install the modules in question and asks what to do. sudo is one option, I usually choose that. cpan will then compile and test new modules in that user's $HOME/.cpan and when it comes to installation it'll ask you for root's (or your) password (depends on settings in /etc/sudoers).
There's also a setting for the maximum size of the ~/.cpan/build directory. Run:
$ cpan
$ o conf build_cache
and see what the current setting is. For me it's [100] which means 100 MB. Type (e.g.)
$ o conf build_cache 50
$ o conf commit
to set it to 50 MB. The cpan shell will instruct you further.
I'm not perfectly sure but I think you need to run the clean command afterwards to actually reduce the size of ~/.cpan/build, i.e. (in the cpan shell):
$ clean

Just delete it.
All of the files in that directory are temporary files generated while installing or upgrading modules from CPAN. They are not required after the install is complete.
You may want to teach your system administrator about the cpanm tool, which is a bit easier to use, and does some automatic cleanup of its temporary files.

there is a process that will have high cpu usage if you delete the cpan folder. I forgot what process it is, but it scans files

Related

can I safely clone perl lib to another location on a computer?

I have my own personal perl instance, using perlbrew and a local cpan instance. I put in a bit of effort to get cpan to work for my local install. I've configured code and tested it using this perl.
I now want to ensure anyone on the computer can use the perl code I wrote, meaning ensuring that the cpan modules I used are available to all, even those that can't access my home directory.
Unfortunately, I can't configure and use cpan as root user. There are a few reasons why this would be difficult, but the biggest is that I am using my personal cert to authenticate myself as part of connecting to the CPAN repo (needed due to the configuration of the system). I don't want to make my cert available to everyone for connecting to CPAN.
I'm wondering if, instead of fixing the root cpan instance and trying to hunt down all the modules I'm using with cpan, I can simply copy the modules I already have. I'm running with the same perl version and on the same architecture, so the modules in my personal home directory should be the right ones.
The problem is that perllocal.pod seems to hard code locations relative to where my instal was done, so a simply copy paste is not enough. Is there another easy way, possible a perl utility, to copy my local CPAN modules and perl lib directory over to the root perl lib directory?
Probably, but why don't you just give them permission to your perlbrew-installed perl. Then just continue to use #!/home/ikegami/usr/perlbrew/perls/5.22.0t/bin/perl or whatever.
If you don't know exactly what you have installed, you could have a look at Dist::Surveyor
If you already know what all of your deps are, you can list them in a cpanfile and then take a snapshot with Carton and use the generated cpanfile.snapshot to install the correct versions in the new location
you can clone the whole CPAN to your server for everyone to install
minicpan -l ~/CPAN -r http://ppm.activestate.com/CPAN/ [-f]

How can I move PERLBREW_ROOT to another directory?

I use perlbrew to manage my Perl environment.
When I installed perlbrew the first time as per the documentation, it installed everything to ~/perl5/perlbrew, which I now find undesirable.
The documentation states:
The directory ~/perl5/perlbrew will contain all install perl executables, libraries, documentations, lib, site_libs. In the documentation, that directory is referred as "perlbrew root". If you need to set it to somewhere else because, say, your HOME has limited quota, you can do that by setting PERLBREW_ROOT environment variable before running the installer:
export PERLBREW_ROOT=/opt/perl5/perlbrew
curl -kL http://install.perlbrew.pl | bash
Question: How can I move PERLBREW_ROOT directory to be /opt/perl5/perlbrew instead of ~/perl5/perlbrew?
Unfortunately, you cannot simply move an installed Perl. For starters, the paths added to #INC are hardcoded. I present you four solutions, of which I recommend the third.
But first, I recommend using /opt/perlbrew instead of /opt/perl5/perlbrew since there's no need for the extra level. The code snippets below assume you followed this recommendation.
Start from scratch, reinstalling any build of perl you had.
Con: For each build, you'll also have to reinstall any modules that build had installed. This means you'll need to retest all your applications. This is time consuming, and not without risk.
Move the perlbrew directory, but attempt to fix the installations.
Move the installation as follows:
mv ~/perl5/perlbrew /opt/
# Adjust file ownership and permissions as desired.
Then, edit the paths in each of the files printed by the following:
for q in /opt/perlbrew/perls/* ; do
"$q/bin/perl" -le'
use Config;
require "Config_heavy.pl";
print $INC{"Config.pm"};
print $INC{"Config_heavy.pl"};
'
done
You'll also need to edit the shebang (#!) line of many scripts.
Con: Lots of work (though not nearly as much as the first option), fragile, and not guaranteed to work.
Create future builds in /opt/perlbrew, but keep existing builds where they are.
After installing perlbrew in /opt/perlbrew, run the following:
cd /opt/perlbrew/perls
for q in ~/perl5/perlbrew/perls/* ; do
ln -s "$q"
done
Pro: Super simple and quick. Over time, you can phase out your ~/perl5/perlbrew (by deleting unneeded builds, by replacing them as per option 1, or by moving them as per option 2).
Con: Everyone that should have access to /opt/perlbrew also needs access to your ~/perl5/perlbrew.
Don't change PERLBREW_ROOT. Simply make /opt/perlbrew a symlink.
ln -s ~/perl5/perlbrew /opt/perlbrew
Pro: Super simple and quick.
Con: Everyone that should have access to /opt/perlbrew also needs access to your ~/perl5/perlbrew.

How to make a Dist::Zilla based Perl module (or app) install files into /etc/?

I maintain multiple Perl written (unix-ish) applications whose current installation process consists of a manually written Makefile and installs configuration files into /etc/.
I'd really like to switch their development to use Dist::Zilla, but so far I haven't found any Dist::Zilla plugin or feature which allows me to put given files into /etc/ when the make install (or ./Build install in case of using Module::Build instead of ExtUtils::MakeMaker) is run by the local administrator who's installing my application.
With pure ExtUtils::MakeMaker, I could define additional make targets in MY::postamble and the let the install target depend on one of them via the depend { install => … } attribute. Doing something similar, but via dzil build, would probably suffice, but I'd appreciate a more obvious way.
One orthogonal approach would be to make the application not to require the files under /etc/ to exist, but for just switching to Dist::Zilla that seems to much change in the actual code despite I only want to change the build system for now.
For the curious: the two applications I currently have in mind for switching to Dist::Zilla are xen-tools and unburden-home-dir.
The best thing to do is to avoid installing files into /etc from any Perl distribution. You cannot ensure that the cpan client (or the installing user) has permissions to install there, and there can be multiple Perls installed on a system, so each one of them would clobber the /etc files of another install. You can't really prevent the file from being overwritten by a subsequent install, so you shouldn't put config data there that you don't want to lose.
You could put the config file in /etc/, if the application knows to look for it there, but you should allow for that path to be customized (say on a test system, look for the file in the local directory, or in a user's home directory).
For installing read-only module-specific data, the best practice in Perl is to install into a Perl-install-specific location, and the module to do that is File::ShareDir::Install. You can use it from Dist::Zilla using the [ShareDir] plugin, Dist::Zilla::Plugin::ShareDir. It is even included in the [#Basic] plugin bundle, so if you use [#Basic] in your dist.ini, you don't need to do anything at all, other than drop your data files into the share/ directory in your distribution repository.
To access the contents of the sharedir from code, use File::ShareDir.
For porting a complex module installer to Dist::Zilla, I recommend my plugins MakeMaker::Custom or ModuleBuild::Custom, depending on which installer you prefer. These allow you to keep your existing Makefile.PL or Build.PL and just have Dist::Zilla plug in necessary bits like the dependencies.

How to install Perl offline

I have a Linux server that has no access to the internet (access is prevented by a firewall). I would like to install a new Perl. What are my options and what is the best way to do this? The system Perl (included in OS installation) must remain unchanged.
I have been using perlbrew and I think it is the best way to do an online installation. But all the steps involved in perlbrew seem to require internet access: you download it from the net, it downloads new Perl versions from the net etc. and I haven't found a glue how to make it work offline.
If perlbrew is out of question I could build Perl from source into a custom location on the server. I assume that this could end up being complicated, time-consuming and error-prone. And every time I update Perl I have make a new build manually.
There can also be other ways to install that I'm not currently aware of. And of course I could stick with the system Perl but it is an outdated version and I'm already using the new syntax features. Or I could start negotiations to change the firewall policy to allow internet access for perlbrew.
But all the steps involved in perlbrew seem to require internet access
Not if properly configured.
To install perlbrew itself off-line, install the App-perlbrew dist. Following its dependencies manually is a chore, so instead prepare a MiniCPAN mirror (with -p to include Perl dists), take it over to the target machine and configure CPAN to use the local mirror. Run cpan App::perlbrew to install.
After perlbrew is installed, run its mirror command to configure a CPAN mirror into $PERLBREWROOT/Config.pm. Edit this file to change it to the local MiniCPAN mirror. Drop Perl dist tarballs into $PERLBREWROOT/dists/.
Be aware that compiling Perl requires a working C compiler toolchain, and optionally the development files for libdb (BerkeleyDB) and gdbm. (Read the INSTALL file once over, even though perlbrew's autoconfiguration and Perl's configure.SH defaults hide these details from you.)
The compiler toolchain is probably much more difficult to procure off-line, unless the OS installation has already been used before for compiling other C stuff.
There's nothing that special about perlbrew. If you aren't going to use it to download the Perl sources, it's not saving you that much. Once you have the Perl sources, you just need to configure and install it:
% ./Configure -des -Dprefix=/path/to/installation
% make install
Once done, everything for that Perl is under that installation path.
I dislike perlbrew mostly because it hides from people how amazingly simple this task is so they feel like they can't do it on their own.
Have you considered attacking it from a different direction? Keeping this up-to-date is going to be a pain if you have to request internet access each time. Likewise, if you've missed out/misconfigured any packages in your CPAN mirror it's difficult to correct once you're actually trying to use them.
Perhaps just build a small VM with a cut-down linux + perl + modules. Keep that up-to-date at your end and just take the whole lot in on a USB stick. You'd have a known-working easy-to-setup installation.
What I personally do is using git checkout when I'm offline (and not on vacation). Once you have the whole git work directory, it's trivial to build any released version by checking out the tags:
git checkout v5.17.4
git clean -f # cleanup previously compiled .o files etc
sh ./Configure ...
Depending on how you can transfer files to your host, this can be handy, since you you can also setup a private git repo there so other computer can git push new commits to there.

How to install packages/programs from sunfreeware to home directory without root access

I on solaris 10 and I wanted to install the latest version of emacs.
I don't have root access. I tried compiling emacs 23.4 from source and I am struck due to an old version of compiler in my system.
I am trying to use the per-built binary from sunfreeware.com, Is there a means to install it in my home directory without root access?
It should be possible for most packages as long as their binaries support to be relocated.
You first need to convert the pkg files to their filesystem variant with pkgtrans, then, in most cases, you also need to extract the embedded archive which is just a cpio file.
Finally, you will need to adjust file permissions using the prototype file and possibly tweak some files or environment variables like LD_LIBRARY_PATH to have the program or libraries be functional.
Of course this can become quite cumbersome when you have to repeat all of this for every dependency the initial package might have.
I don't know about emacs but I suspect it to have many dependencies so the technique I suggest here might be too complex to worth the effort, especially as emacs has an alternative which is always installed and that many people prefer, I mean of course vi.