Category Archives: Sysadmin

Common issues building CPAN Perl modules to RPMs

Recently I’ve been compiling several Perl modules for installation on new CentOS 7 machines because we’ll be using it to deploy several Catalyst and Mojolicious applications.

The tools

I’ve mainly used the following tools

  • cpanspec – generates spec files for Perl modules from CPAN available through yum in epel repos:

    sudo yum install cpanspec

  • rpmbuild – build rpm packages, available in rpm-based systems

The cycle

cpanspec -v --packager "My Packager Name" GD::SecurityImage
mv *.spec rpmbuild/SPECS/.; mv *.tar.gz rpmbuild/SOURCES/.
rpmbuild -ba rpmbuild/SPECS/perl-GD-SecurityImage.spec

Common issues – and work-arounds

My main purpose in writing this post was to compile and share the most common issues I ran into while building RPMs from CPAN modules. Hope this helps you and probably my future-self.

Modules using Module::Build::Tiny

(solved in cpanspec master with Leon’s PR) CPAN modules that use Module::Build::Tiny instead of the most commonly used Module::Build present the following error:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: Can't create '/usr/local/share/man/man3'
Do not have write permissions on '/usr/local/share/man/man3'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 at /usr/local/share/perl5/Module/Build/Tiny.pm line 119.

(if you don’t, I’d guess you’re building the modules with root, which can get you in a lot of trouble)

This is caused by the lack of support by the Tiny module of all the types of arguments available in Module::Build (this is not really a bug but a design option). The arguments passed should have the -- prefix (check Leon’s comment on the subject), so, the solution is to edit the spec file and in the sections %build and %install fix the arguments:

--installdirs
--destdir
--create_packlist

Now you can run rpmbuild and everything should be fine.

Packages hidden from PAUSE

For some reason (please tell me why) many distributions hide some namespaces from PAUSE (Perl Authors Upload Server) – HTML::FormHandler example. This causes yum to fail on install, which is quite unpleasant.

Error: Package: perl-HTML-FormHandler-0.40059-1.el7.centos.noarch (/perl-HTML-FormHandler-0.40059-1.el7.centos.noarch)
           Requires: perl(HTML::FormHandler::Meta::Role)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

A side-effect of hiding the namespace from PAUSE was that neither cpanspec or rpmbuild was able to identify that the HTML::FormHandler::Meta::Role was provided by that same module and listed it as a dependency. You could just add AutoReq: no after the remaining Requires in the spec file but I find that a better work-around is to add:

Provides:       perl(HTML::FormHandler::Meta::Role)

so that rpmbuild and remaining tools now know that this module already has that class. rpmbuild/SPECS/perl-HTML-FormHandler.spec -> Provides

Missing files in MANIFEST – Installed (but unpackaged) file(s) found

Some packages just don’t include all the files that they provide (e.g. Test::Harness):

error: Installed (but unpackaged) file(s) found:
   /usr/bin/prove
   /usr/share/man/man1/prove.1.gz

The solution is simple: just double-check that nothing out of the ordinary is there and add the list to the %files spec section. Just copy & paste – that easy.

Bogus paths

Not all module packages are created equal, and some of them, are bogus…

BOGUS PATH DETECTED: PDF-Table-Version_0.9.7/
...
Skipping PDF-Table-0.9.7.tar.gz with 24 path elements!

To fix this issue you’ll need to re-package the module but it should be rather easy:

mkdir tmp
cd tmp/
tar xzvf ../PDF-Table-0.9.7.tar.gz
mv PDF-Table-Version_0.9.7/ PDF-Table-0.9.7/
tar czvf PDF-Table-0.9.7.tar.gz PDF-Table-0.9.7
cp PDF-Table-0.9.7.tar.gz ../
cd ..
cpanspec PDF-Table-0.9.7.tar.gz

Now you’ll be able to successfully create your .spec file and continue building that module.

Polluted environment – File not found

An error that got me spinning around for hours occurred when rpmbuild could not find some build files, around the lines of:

RPM build errors:
 File not found by glob

I think this is caused by CPAN it might alter your environment with something similar to:

PERL_MM_OPT=INSTALL_BASE=/home/rpmbuild/perl5

As a work-around it’s possible to just unset the constant:

unset PERL_LOCAL_LIB_ROOT
unset PERL_MM_OPT
unset INSTALL_BASE
unset PERL_MB_OPT

See also

Changelog

  • Thanks to Thibault for PERL_MB_OPT

IP range routing – some steps into routing debugging

Recently, I had some issues with IPs not being routed to my server. The first time something like this happened I ended up locking myself out with bad network configurations and no network access to the machine. But well, learning from my mistakes, I now was able to avoid that scenario. Although, I was still struggling to get the IPs set-up on the server. Turns out, the IP range wasn’t being routed to my server.

What I learned from this situation was how to better interpret traceroute output, and some routing mechanics. As I understand it now, routers are usually configured in a rather “lazy” way. So, even if the router already has a routing rule configured for the server, it will only “come to live” in the traceroute after the IP is configured on the server. That could be as easy as:

# ifconfig eth0:1 104.121.70.190 up

After that, if the router is configured correctly it’ll go from CASE 1 to CASE 3. By analysing the last ip in the traceroute we should be able to see the router’s IP (in my case 64.120.243.194) as the last entry. If it’s not there, there’s most likely an issue with the routing tables.

Some other useful commands for testing the traffic going through:

  • # tcpdump -i any icmp – View all ping requests going through any interface
  • # nmap -sP -PN --traceroute --reason -n 104.121.70.190 – friendlier output for traceroute

These 3 cases illustrate some different scenarios and will definitely help me analyse future routing issues.

CASE 1: IP not routed to any server – ends up without any further response, and never seeing your ip in the “path”

If you have the IP configured on the server, this probably means the router is still not correctly configured.

$ sudo traceroute 104.121.70.190
traceroute to 104.121.70.190 (104.121.70.190), 30 hops max, 60 byte packets
1 dsldevice.lan (192.168.1.254) 0.873 ms 1.032 ms 1.217 ms
2 * * *
3 bl3-73-29.dsl.telepac.pt (213.13.73.29) 14.384 ms 14.681 ms 14.955 ms
4 lis1-cr1-hu4-0-0.cprm.net (195.8.10.25) 10.341 ms 10.317 ms 10.277 ms
5 mia1-cr1-te0-0-0.cprm.net (195.8.0.178) 84.083 ms 84.048 ms 84.008 ms
6 xe-8-3-0.mia10.ip4.tinet.net (77.67.78.85) 81.857 ms 77.271 ms 76.924 ms
7 xe-2-3-0.nyc41.ip4.tinet.net (141.136.111.9) 111.017 ms 112.177 ms 112.652 ms
8 gtt-gw.ip4.tinet.net (199.229.230.94) 115.666 ms 112.209 ms *
9 ae3-80g.cr1.ewr1.us.nlayer.net (69.31.94.117) 110.117 ms 110.881 ms 110.557 ms
10 xe-0-0-3.cr1.phl1.us.nlayer.net (69.22.142.161) 114.189 ms 113.830 ms 114.311 ms
11 198.47.110.30 (198.47.110.30) 118.809 ms 117.353 ms 117.998 ms
12 tn1-02.cor01.dupa01.hostnoc.net (96.9.191.2) 117.775 ms 118.002 ms 117.150 ms
13 vl0201.agg01.ded.dupa01.hostnoc.net (64.120.184.166) 118.866 ms 117.849 ms 118.208 ms
14 vl0107.bl1101.dupa01.hostnoc.net (64.120.243.194) 119.561 ms 119.607 ms 118.369 ms
15 * * *
16 * * *
17 * * *
18 * * *
19 * * *
20 * * *
21 * * *
22 * * *
23 * * *
24 * * *
25 * * *
26 * * *
27 * * *
28 * * *
29 * * *
30 * * *

CASE 2: IP routed to server but not configured (bounces between the “last” router and the server main ip)

Note: as I later noticed this only happens after the server had already been configured to use that ip but it’s removed. This causes the server to not find a rule

$ sudo traceroute 104.121.70.190
traceroute to 104.121.70.190 (104.121.70.190), 30 hops max, 60 byte packets
1 dsldevice.lan (192.168.1.254) 1.161 ms 1.396 ms 1.659 ms
2 * * *
3 bl3-72-29.dsl.telepac.pt (213.13.72.29) 14.358 ms 14.339 ms 14.300 ms
4 lis1-cr1-hu4-0-0.cprm.net (195.8.10.25) 8.523 ms 14.215 ms 14.174 ms
5 mia1-cr1-te0-0-0.cprm.net (195.8.0.178) 92.087 ms 92.061 ms 92.023 ms
6 xe-8-3-0.mia10.ip4.tinet.net (77.67.78.85) 82.328 ms 77.430 ms 77.307 ms
7 xe-2-3-0.nyc41.ip4.tinet.net (141.136.111.9) 111.292 ms 112.534 ms 111.403 ms
8 gtt-gw.ip4.tinet.net (199.229.230.94) 114.183 ms 115.369 ms 116.087 ms
9 ae3-80g.cr1.ewr1.us.nlayer.net (69.31.94.117) 112.315 ms 119.415 ms 115.055 ms
10 xe-0-0-3.cr1.phl1.us.nlayer.net (69.22.142.161) 115.342 ms 113.859 ms 113.820 ms
11 198.47.110.30 (198.47.110.30) 118.461 ms 117.984 ms 116.879 ms
12 tn1-02.cor02.dupa01.hostnoc.net (96.9.191.6) 310.551 ms 309.764 ms 308.366 ms
13 vl0202.agg01.ded.dupa01.hostnoc.net (64.120.184.170) 118.070 ms 117.617 ms 118.814 ms
14 vl0107.bl1101.dupa01.hostnoc.net (64.120.243.194) 120.308 ms 120.045 ms 120.357 ms
15 104-121-50-210.static.hostnoc.net (104.121.50.210) 119.878 ms 120.898 ms 121.256 ms
16 104-121-50-209.static.hostnoc.net (104.121.50.209) 124.838 ms 120.848 ms 120.891 ms
17 104-121-50-210.static.hostnoc.net (104.121.50.210) 117.659 ms 116.994 ms 118.228 ms
18 104-121-50-209.static.hostnoc.net (104.121.50.209) 119.360 ms 119.217 ms 126.278 ms
19 * * *
20 104-121-50-209.static.hostnoc.net (104.121.50.209) 118.766 ms 124.257 ms 124.143 ms
21 * * *
22 104-121-50-209.static.hostnoc.net (104.121.50.209) 122.279 ms 124.911 ms 123.907 ms
23 * * *
24 104-121-50-209.static.hostnoc.net (104.121.50.209) 119.758 ms 119.936 ms 119.309 ms
25 * * *
26 104-121-50-209.static.hostnoc.net (104.121.50.209) 124.762 ms 122.253 ms 122.464 ms
27 * 104-121-50-210.static.hostnoc.net (104.121.50.210) 123.030 ms 122.997 ms
28 104-121-50-209.static.hostnoc.net (104.121.50.209) 124.775 ms 125.393 ms 125.737 ms
29 104-121-50-210.static.hostnoc.net (104.121.50.210) 125.112 ms 125.075 ms 125.330 ms
30 104-121-50-209.static.hostnoc.net (104.121.50.209) 126.358 ms 128.547 ms 128.903 ms

CASE 3: IP routed and configured on the server

$ sudo traceroute 104.121.70.190
traceroute to 104.121.70.190 (104.121.70.190), 30 hops max, 60 byte packets
1 dsldevice.lan (192.168.1.254) 0.793 ms 1.018 ms 1.243 ms
2 * * *
3 bl3-72-29.dsl.telepac.pt (213.13.72.29) 8.450 ms 8.421 ms 8.383 ms
4 lis2-cr1-hu-3-0-0.cprm.net (195.8.10.201) 10.058 ms 10.035 ms 10.228 ms
5 mia1-cr1-te1-4-0.cprm.net (195.8.0.182) 85.074 ms 85.051 ms 85.234 ms
6 xe-8-3-0.mia10.ip4.tinet.net (77.67.78.85) 81.829 ms 77.844 ms 77.432 ms
7 xe-2-3-0.nyc41.ip4.tinet.net (141.136.111.9) 111.521 ms 111.487 ms 113.351 ms
8 gtt-gw.ip4.tinet.net (199.229.230.94) 117.949 ms 118.190 ms 117.317 ms
9 ae3-80g.cr1.ewr1.us.nlayer.net (69.31.94.117) 113.542 ms 113.215 ms 114.055 ms
10 xe-0-0-3.cr1.phl1.us.nlayer.net (69.22.142.161) 119.913 ms 119.754 ms 119.074 ms
11 198.47.110.30 (198.47.110.30) 123.665 ms 123.872 ms 124.098 ms
12 tn1-02.cor01.dupa01.hostnoc.net (96.9.191.2) 123.589 ms 124.269 ms 123.245 ms
13 vl0201.agg01.ded.dupa01.hostnoc.net (64.120.184.166) 123.177 ms 124.095 ms 123.898 ms
14 vl0107.bl1101.dupa01.hostnoc.net (64.120.243.194) 120.727 ms 122.194 ms 122.494 ms
15 104-121-50-210.static.hostnoc.net (104.121.50.210) 124.726 ms 123.289 ms 123.663 ms
16 104-121-70-190.static.hostnoc.net (104.121.70.190) 123.720 ms 125.139 ms 124.116 ms