the first productive days with Pinto

After a while I could convince our admin at $work to prepare a virtual machine for running a Pinto server inside our company network. The primary goals were to have a well-known set of CPAN distributions available for installing developer machines, for running CI tests and for provisioning all kinds of servers.

The first part of work to get done was installing all relevant parts needed to run the Pinto server. We decided to use a standard Apache setup with two virtual hosts: one for uploading onto the Pinto server (listening on port 8080) and one for CPAN clients (listening on port 80). Apache's document root for CPAN clients points to the "stacks" directory inside Pinto's repository allowing URLs starting with the stack name. A later expansion will add authentication for the Pinto virtual host but currently the reachability is strongly limited so we can live without for the moment.

But wait -- how can we reach the goals by using Pinto?

First, we are maintaining a growing number of distributions containing company-wide usable modules for common tasks among various projects we are working on. Many of these modules do very special tasks or contain customer-specific business logic and may not get uploaded to CPAN. To allow installing them by using a CPAN client every developer creating or updating such a distribution is kindly asked to upload it to a prepared stack (let's name it "global" here).

Every distribution basically has such a setup in its dist.ini file (we are using a PluginBundle but basically this would be the manual way).

-bundle = @Basic
-remove = UploadToCPAN

root          =
author        = COMPANY
stack         = global
no_recurse    = 1
authenticate  = 0

This allows a developer to upload a freshly updated distribution via

dzil release

Everybody else may simply install the distribution instead of checking out the latest version from the distribution's git repository and building a distribution for a local install.

cpanm --mirror Distribution::Name

The next topic to solve was to find a way to bundle all distributions needed to run or deploy a project. Our projects (mostly Catalyst apps) are containing a Makefile.PL holding all required distributions.

This turns out to be a simple task. All distributions our app is depending on are recursively pulled to a given stack ("proj" here in this example). Later, additional fine tuning may improve the distribution selection by pinning, pulling or adding selected distributions.

All subsequent pinto commands assume the existence and proper setup of an environment variable PINTO_REPOSITORY_ROOT containing the URL of the pinto server.

cpanm --showdeps . | xargs pinto pull -s proj

Using the "pull" command has an interesting side effect. Trying to pull a distribution which is kept anywhere inside Pinto's repository magically works. There is no need to get this distribution from one of the official CPAN mirrors. So our decision to maintain a "global" stack containing all company-distributions turned out to be a wise decision. (I hope this behavior was intentional and will stay for future versions of Pinto.)

When we now need an installation we may simply get all required distributions in predictable versions from our bundled stack for a project.

cpanm --mirror --mirror-only --installdeps .

The "--mirror-only" option prevents cpanm from doing its usual fallbacks. Of course, it is a matter of taste. An installation will fail if a distribution is missing but if all distributions are present, you know the version of all of them.


1 Comment

Trying to pull a distribution which is kept anywhere inside Pinto's repository magically works. ... (I hope this behavior was intentional and will stay for future versions of Pinto.)

It was very much intentional. Pinto tries to satisfy prerequisites with whatever modules it already has. This helps large organizations stay (or converge) on a relatively consistent set of modules/versions across all their products.

Leave a comment

About Wolfgang Kinkeldei

user-pic I blog about Perl.