Using Carton and plenv to install application expected versions of perl and modules that doesn't require root access nor replace the system installed versions of perl.
2. - Years ago, perl developers required root
access to install modules
- Admins reluctant to hand over reins and
security policies restricted it
- use lib and @inc could get around
some problems
- perl bundled with OS always lagged
behind
- enter the tools
What?
• Removing dependency on root access
• providing consistent environments
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
3. - going to start with plenv
How to avoid root access
• plenv
• carton
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
4. - Written Tokuhiro Matsuno
- plenv is implemented in bash, and
provides simple shell script wrappers
(called "shims") for each perl
executable files.
- perl is installed in user space and
doesn't require any special
permissions.
plenv - perl binary manager
https://github.com/tokuhirom/plenv
Written by: Tokuhiro Matsuno
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
5. - Taken directly from the GitHub
project page
- perls are installed in your home
directory
- implemented in bash with simple
shell script wrappers called shims
- the shims provide access to perl
executable files (carton, cpanm, prove)
plenv vs. perlbrew
Like perlbrew, plenv installs perls under your home directory and lets you
install modules locally, and allows you to switch to arbitrary perl versions on
your shell.
Unlike perlbrew, plenv is implemented in bash, and provides simple shell script
wrappers (called "shims") for each perl executable files. It doesn't export any
shell functions that switches PATH before running commands.
Unlike perlbrew, plenv allows you to set local perl version per directory,
using .perl-version file.
Unlike perlbrew, plenv doesn't provide built-in local::lib integrations, but
plenv-contrib implements use and lib commands for a replacement
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
6. - there are multiple choices for
installation to fit your needs
- The installation page goes
into detail
plenv Installation
https://github.com/tokuhirom/plenv#installation
• macOS via homebrew
brew install plenv perl-build
• via git clone
git clone https://github.com/tokuhirom/plenv.git
~/.plenv
• manual/neckbeard
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
7. - plenv help provides an
overview and can provide
details per command
- We're going to look at some
of these commands more in
depth
plenv help
Extensive online help system
through plenv
Each command has its own help
via plenv help <command>
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
8. - You can see here that I have multiple
installations of the same version
- each of these is a directory that
contains everything required for perl
to run
- the -debug version is built with
additional flags, I'll come back to this
perl binary manager
• Installs perl in ~/.plenv
• each directory contains an entire
perl installation
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
9. - versions of perl that are available to
install
- This is a command that I always
forget
- There are a lot of versions available,
including Release Candidates, Trials,
cutting edge and ones you really
shouldn't be running
What versions can I build?
plenv install --list lists all
versions that can be installed.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
10. - allows you to create a custom install of perl per
project
- using the as directive gives the perl installation a
custom name
- names can be anything, and are useful for matching
projects
or options specified
- if you have modules that need to be installed for a
project, using
a project specific perl installation will keep the
modules separate
Custom versions per project
The --as directive allows the name
of the installed perl to be
changed.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
11. - build options can be passed to
install
- build in parallel
- yes, this project required threads
- there's no need to install man
pages for all perl versions
- unique name to identify
Adding options to perl build
Add options to the build directly
on the command line
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
12. - plenv allows control of perl versions
in different scenarios
- the scope of use increases through
the list
- if a version is not set, plenv will default
to system perl, which is whatever is
installed with the OS
- this can lead to undesirable results
Selecting a version to use
Sub commands for setting perl version:
• local
• shell
• global
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
13. - sets the perl version via .perl-
version file in the current directory
- simple text file containing the version
to use, so automation tools can write it
- automatically searches up directory
tree, which you can see here with the
cd lib
In directory tree
• uses the local subcommand
• also write the .perl-version file
manually
• specific to the working directory
tree
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
14. - sets the version for the current shell
- version stays in place until:
- shell is closed
- new version requested
- enter directory with a .perl-version file
- or the shell is --unset
- as a side note, does not work with fish shell, to
get around this set the PLENV_VERSION
environment variable
- in fact that's how we test with Jenkins
Shell
• uses the shell subcommand
• specific to the current shell
• use the --unset option to revert
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
15. - The global setting sets a
common perl version to be
used
when none other is set
- To use within cron a login
shell is required bash -lc
Global
• uses the global subcommand
• sets the default used for the
system
• only works in shells that have
been initialized with plenv
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
16. - if home directories are an NFS
or limited space in partition
- overriding the plenv defaults
using environment variables
- plenv init is called to
continue environment setup
Change installation directory
• Useful if $HOME isn't a good place
to store perl installations
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
17. - Modules kept within the perl
version's directory
- each perl version has its own
set of modules
Where are the modules
stored?
Modules are contained along with
other perl files
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
18. - plenv has built in support
for installing cpanminus
- automatically installs and
runs plenv rehash
CPANMINUS?
plenv install-cpanm
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
19. - the plenv which command
shows the full path to the
script/bin that will be executed.
- plenv rehash updates the
shims that allow commands
to be executed
What's rehash?
Packages that install scripts or bin/ are also stored by perl version.
When new scripts/bins are installed plenv rehash must be run to update the shims.
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
20. - to install a version upgrade, just
use plenv install
- migrate-modules reads the
previous versions module and
installs them for the new
version.
Upgrading
Same as installing a new version.
migrate-modules re-installs all modules into the new version
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
21. - Handles installation and
configuration for all of these
environments
And while you're managing
plenv
Why not manage all the envs!
anyenv - all in one for **env
https://github.com/riywo/anyenv
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
23. - maintains a list of required
versions and dependencies
- allows locking down specific
versions of modules
- managed through
cpanfile
Carton
Carton - Perl module dependency manager (aka
Bundler for Perl)
https://github.com/perl-carton/carton
Written by: Tatsuhiko Miyagawa
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
24. - installation with cpanm in a
fresh install
Installing with plenv
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
25. - Another Miyagawa creation
- Modules are specified using the
requires keyword
- optional minimal version numbers can
be specified using the =>
'<version>' construct
- version ranges, and exact versions can
be specified with operators
Version management
Modules are managed through a
cpanfile.
More on cpanfile can be read here
https://metacpan.org/pod/cpanfile
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
26. - reads the cpanfile and installs
modules and dependencies using cpanm
- All modules are installed in local/
directory
- After modules are installed carton reads
the contents of local/ and writes
a cpanfile.snapshot
Installing modules
carton install reads the cpanfile file and installs modules and dependencies.
All modules are installed in the local/ directory.
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
27. - local/ directory is identical
to the system directories
- bin/ contains scripts and
binaries
- lib/ standard perl module
structure with perl5 directory
Contents of local
The local/ directory contains subdirectories of module contents.
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
28. - the carton exec command establishes
the shell environment for script/command
execution
- local/bin scripts/commands are in the
path and can be called directly
- other commands can be executed using
perl
- it's also possible to carton exec --
bash to set environment within the shell
Execution with carton
The carton command will also set
the shell environment to use the
local/ directory.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
29. - File is automatically
generated by carton
install
- both a blessing and a curse
What is the cpanfile.snapshot?
Maintains a list of all installed
modules, what they provide,
versions, and dependencies.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
30. - extremely useful for maintaining
a consistent development
environment
across developers
- maintains versions between
development, test, QA and
production
Locking down versions
When installing with the --deployment option, carton installs versions
specified in cpanfile.snapshot.
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
31. - there are some difficulties with
carton
- there used to be more, but when
trying to replicate them, they didn't
occur again
- most gotchas revolve around
maintaining the cpanfile.snapshot
Gotchas
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
32. - suspect that cpanm is failing
to parse META.yml and the
result
is that the provides includes
and undef version number
Modules with malformed
META.yml or META.json files
provides includes an undef version
number.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
33. - Example of cpanfile.snapshot with
File::HomeDir that's required
by sqitch on Mac, get a diff with it being deleted
- In this instance a co-worker installed a new
module, but during
the scan by carton install the Mac-
SystemDirectory module was
removed from cpanfile.snapshot
- Must be careful when removing modules
Module not required
Difference between Linux and Mac
requirements can cause different
cpanfile.snapshot contents.
Divorcing System // Toronto Perl Mongers // Shawn
Sorichetti
34. - using this method (discovered by Cees) mitigates a lot of issues
- First install the versions specified in cpanfile.snapshot
- update the cpanfile with the new requirements
- Use cpanm to install any modules and dependencies into
local/
- run carton install to update the cpanfile.snapshot
- the tricky part is the commit, make sure not to include anything
that might
be updated.
- To be thorough, remove rm -fr local/ and run carton
install --deployment
again
Using cpanm to add/update modules
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
35. - Everything is stored in
local/
- no breakout by version
- adding separation isn't too
difficult
Upgrading Perl
There is no disconnection between local/ directories
and perl versions.
Carton does not have a concept of perl version, any
module that isn't pure perl
or is platform dependent requires recompilation.
There is a manual solution!
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti
36. - move the existing local directory out of the way
- plenv version-name returns only the
version name
- create a symbolic link from the perl version to
local
- install the new version of perl
- set the perl version, install cpanminus, and Carton
- create a new versioned local directory
- re-point the symbolic link
- now install everything else
Upgrading Perl
Divorcing System // Toronto Perl Mongers // Shawn Sorichetti