In this article and in the ensuing articles in this series, the author will be highlighting a resurgent Perl.
Perl was called the duct tape of the Internet by its developers. And it still holds together a lot of Net based tools – the best example being Bugzilla, the open source bug tracking tool.
With more DevOps roles popping up in the cloud space and after the release of Perl 6, this programming language is seeing a resurgence. In this article, we will gauge Perl 5 and probably look at Perl 6 in a different series. Pearl 5 has one of the greatest communities around it and is growing stronger!!
Perl is an excellent tool, and you could call it the Swiss army knife of programming languages, especially when it comes to one liners. This we will see in future articles of this series, where we will use one liners to start up a Web server in Perl.
For now, let us look at setting up a Web service (if not a server) for Perl, the old fashioned way, which still runs well for products like Bugzilla.
Types of Perl Web services
Listed below are some of the common Perl Web services.
1. CGI (Common Gateway Interface)
- mod_cgi
- FCGI
- mod_perl – This is the fastest method to implement CGI scripts and add more functionality. This is officially supported only till Apache 2.2, though it works in Apache 2.4.
2. PSGI (Perl Web Server Gateway Interface aka its middleware)
- Plack – This is a set of tools for using the PSGI stack. It contains middleware components, a reference server and utilities for Web application frameworks. Plack is like Ruby’s Rack or Python’s Paste for WSGI– (github.com/plack/Plack)
- Web frameworks – Examples include Catalyst, Dancer, Mojolicious, etc
- P6SGI (Server – middleware – application), which we will not go into too deeply in this series.
Main concerns:
- Setting up the middleware using Apache (Web) and CGI/Perl (App)
- Trying out mod_cgi, and also comparing it with mod_perl
- Moving to HTML::Template (decouple Perl code from the HTML/CSS/JS)
- Giving PSGI a try and moving to Plack
- Upgrading to Web frameworks
Requirements
- A desktop or laptop (the OS is not important – even MacOS will do)
- Internet access
If we have a GNU/Linux machine and want to set up Perl/HTML on that itself, then we could go directly to Step 3 (vi) post install instructions on Page 77, copy them to a .sh file and run them as executable; and instead of going to Step 3 (vii), we can go directly to Upgrade Perl section on Page 39.
If you do not have a GNU/Linux box, and want to set up a Web server and application container (in our case, the Perl module) in the cloud, that would be the main motive of this session. Future sessions would have more details on Perl+HTML. Out of all the cloud containers out there, I found AWS to be very fast and intuitive. So we will be doing our Web setup using AWS Free Tier.
Web server for Perl
- Create an AWS Free Tier account using your email address and credit card. (It is very easy to create a free tier account; just Google for the instructions.) You do not need certification for this.
- Before we create our instance, we need to create the following.
i. A key pair
Click on EC2 under the Compute section.
On the left pane, click on Key Pairs under Network & Security. There are two ways to do this.
(a) Let AWS create it for you.
- Click on Create Key Pair.
- Give a Key Pair name.
- Hit Create. This will automatically create the private key (.PEM) and download it to your Browser Downloads section. Save that file and remember the path of the file.
(b) You create it and import it into AWS.
- From Command Line on any OS, we use ssh-keygen to create the private and public key. On pressing enter; it will create id_rsa(private key) and id_rsa.pub (public key) files. (NOTE: AWS only supports RSA keys)
- Using puttygen.exe we can save the private key (.ppk extension) and public key to our machine.
- The pub keys we created in either of the above steps, can be imported into AWS.
ii. Security group
- On the left pane, click on Security Groups under Network & Security.
- Click on Create Security Group.
- Give the name you want along with a description.
- Add the rule under the Inbound default tab.
- Choose HTTP and SSH.
- Hit Create.
3. To create your instance, log in to the console, and go through the following steps:
- Click on EC2 under the Compute section.
- Click on Launch Instance.
- Select your favourite flavour – Amazon, Red Hat, SUSE or Ubuntu. (It has to be one among those that have ‘Free tier’ clearly written.)
- On the following page, click on Next: Configure Instance Details.
- On the configure page, leave everything as is, but go to the bottom and expand Advanced Details.
(a) For Red Hat/Amazon, use the following code:
#!/bin/bash #works for redhat/amazon gnu/linux sudo timedatectl set-timezone ‘America/Los_Angeles’ #timedatectl list-timezones #mod_perl is not supported in RHEL7 by default; EPEL repository does, as of this writing sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm sudo yum -y update sudo yum -y install mod_perl # install apache, perl-5.16(Amazon comes with Perl) and all required perl modules sudo yum -y install vim-enhanced #installing vim editor sytax highlighting support, not required for Amazon Linux sudo ln -sf /usr/bin/perl /usr/local/bin/perl sudo sed -i ‘s/Options\ None/Options\ \+ExecCGI/’ /etc/httpd/conf/httpd.conf sudo su - root -c ‘cat >> /etc/httpd/conf/httpd.conf << EOF <IfModule mod_perl.c> ScriptAlias /cgi-perl/ /var/www/cgi-bin/ <Location “/cgi-perl”> AllowOverride None SetHandler perl-script PerlResponseHandler ModPerl::PerlRun PerlOptions +ParseHeaders Require all granted </Location> </IfModule> EOF’ sudo su - root -c ‘cat > /var/www/cgi-bin/printenv << EOF #!/usr/local/bin/perl print “Content-type: text/plain; charset=iso-8859-1\n\n”; foreach \$var (sort(keys(%ENV))) { print “\$var=”.\$ENV{\$var}.”\n”; } EOF’ sudo chown apache:apache /var/www/cgi-bin/printenv sudo chmod u+x /var/www/cgi-bin/printenv sudo systemctl start httpd
(b) For Suse, use the following code:
#!/bin/bash #works for suse gnu/linux sudo timedatectl set-timezone ‘America/Los_Angeles’ #timedatectl list-timezones sudo zypper -n update #update packages sudo zypper -n install vim-data #installing vim editor sytax highlighting support #perl 5.18 comes installed by default but all required perl modules, including SSL support, get installed with this command sudo zypper -n install apache2-mod_perl sudo su - root -c ‘cat >> /etc/apache2/httpd.conf << EOF LoadModule perl_module /usr/lib64/apache2/mod_perl.so Include /etc/apache2/conf.d/mod_perl.conf EOF’ # Enable server software details to see the mod_perl and perl versions sed -i ‘/APACHE_SERVERTOKENS/c\APACHE_SERVERTOKENS=\”Full\”’ /etc/sysconfig/apache2 sudo ln -sf /usr/bin/perl /usr/local/bin/perl # Create symlink to default perl # Create the perl based printenv script in the actual cgi folder and set permissions right for # apache user to read it sudo su - root -c ‘cat > /srv/www/cgi-bin/printenv << EOF #!/usr/local/bin/perl print “Content-type: text/plain; charset=iso-8859-1\n\n”; foreach \$var (sort(keys(%ENV))) { print “\$var=”.\$ENV{\$var}.”\n”; } EOF’ sudo chown wwwrun /srv/www/cgi-bin/printenv sudo chmod u+x /srv/www/cgi-bin/printenv sudo systemctl start apache2
(c) For Ubuntu, use the following:
#!/bin/bash #works for ubuntu gnu/linux sudo timedatectl set-timezone ‘America/Los_Angeles’ #timedatectl list-timezones sudo apt-get update #perl 5.18 comes installed by default but all required perl modules, including SSL support, get installed with this command sudo apt-get -y install libapache2-mod-perl2 # Unlike other OS, apache web server needs to be separately installed # This will start the apache service as well sudo apt-get -y install apache2 # Enable the CGI & Perl modules cd /etc/apache2/mods-enabled sudo ln -s ../mods-available/cgi.load sudo ln -s ../mods-available/perl.load sudo su - root -c ‘cat >> /etc/apache2/conf-available/serve-cgi-bin.conf << EOF <IfModule mod_perl.c> ScriptAlias /cgi-perl/ /usr/lib/cgi-bin/ <Location “/cgi-perl”> AllowOverride None SetHandler perl-script PerlResponseHandler ModPerl::PerlRun PerlOptions +ParseHeaders Require all granted </Location> </IfModule> EOF’ # Enable server software details to see the mod_perl and perl versions sudo sed -i ‘/^ServerTokens/c\ServerTokens\ Full’ /etc/apache2/conf-available/security.conf sudo ln -sf /usr/bin/perl /usr/local/bin/perl # Create symlink to default perl # Creating the printenv file sudo su - root -c ‘cat > /usr/lib/cgi-bin/printenv << EOF #!/usr/local/bin/perl print “Content-type: text/plain; charset=iso-8859-1\n\n”; foreach \$var (sort(keys(%ENV))) { print “\$var=”.\$ENV{\$var}.”\n”; } EOF’ sudo chown www-data /usr/lib/cgi-bin/printenv sudo chmod u+x /usr/lib/cgi-bin/printenv sudo service apache2 reload
vi. Click Next:Add Storage. If you want, you can increase the storage space to 20. If you want more than that, then check the specifications allowed for free tier. But leave the Volume at just one Root Volume.
vii. Click Next:Add Tags. You can leave this section unless you want to set a tag.
viii. Click Next:Configure Security Group.
- Select the one that you had created in (2)(ii).
- Click Review and the Launch.
ix. Click Launch on the next page, after we are satisfied with our settings.
x. This will give a popup dialogue box in which you have to choose your key pair. If you had created just one key pair (not more), the one you created in (2)(i) will show up as selected, by default. Select the Acknowledgement and click Launch Instances.
xi. In the resultant page, you will get a line that reads as follows:
‘The following instance launches have been initiated:i-059ff3c697315eff8. View launch log.
Click the first alphanumeric string, which will take you to your instance that is being launched.’
4. On the console now, towards the bottom, under the Description section, we can see the IP address to the right of the label — IPv4 Public IP. And to the right of the IP address, there is a small two-page icon, which is clickable. On clicking it, the IP address will get copied to the clipboard. Keep that copied to your notepad.
5. When the Instance State column says it is running, then you are ready to log in to your machine.
6. Step (3)(vi) can be done after logging into the instance or whichever the GNU/Linux machine we want to set up the Web environment on. We can copy-paste those lines into a .sh file, make it executable and run it.
Log in to AWS (only required if using AWS).
What client to use
- This section is required only if connecting to a remote machine and not if we are working on a local machine.
- Command line SSH is built into Windows 10, MacOS and GNU/Linux. In MacOS, we just have to enable it separately. This includes all SSH client tools, e.g., ssh-keygen.
- Putty. (PCs earlier than Windows 10 might need to use Putty. Do check references for installing Putty on MacOS.)
- Any third party SSH client, either open source or commercial.
Authentication
- Using ec2-user@IP-Address (or ubuntu@IP-Address for Ubuntu OS).
- Using the private key created in Step (2) of Web/middleware for Perl (using a password is not allowed in AWS).
- ssh -i “path\to\keypair.pem” useridForOS@IPAddress (if using the command line).
- If using Putty, then you have to convert the .pem file to a .ppk file using the Puttygen application by importing the .pem private key and saving it as a .ppk file. This can be imported into Putty’s Connection/SSH/Auth section.
Upgrading Perl
Ubuntu comes with something that’s very near the latest Perl. But all others come with unsupported Perl. So if we want to upgrade Perl, the string (as of this writing 5.28 is the latest).
This is done under the assumption that we have already run Step (3)(vi) of Web/middleware server for Perl and that we have a running Apache setup with the mod_perl module already installed.
It will do the following:
- Compile the downloaded mod_perl with the latest Perl.
- Overwrite the already existing mod_perl module.
- Reload Apache to activate the latest mod_perl.
#!/bin/bash OSID=`grep ^ID= /etc/os-release | awk -F= '{print $2}' | sed -e 's/\"//g'` case $OSID in amzn|rhel|fedora|centos) sudo yum -y groupinstall "Development Tools" sudo yum -y install httpd-devel ;; sles) sudo zypper -n install --type pattern Basis-Devel sudo zypper -n install apache2-devel ;; ubuntu|debian) sudo apt-get -y install build-essential sudo apt-get -y install apache2-dev ;; esac sudo mkdir -p /usr/local/src/{apache,perl} wget -qO- http://apache.claz.org/perl/mod_perl-2.0.10.tar.gz | sudo tar xvz -C /usr/local/src/apache wget -qO- https://www.cpan.org/src/5.0/perl-5.28.0.tar.gz | sudo tar xvz -C /usr/local/src/perl cd /usr/local/src/perl/perl-5.28.0 sudo ./Configure -des -Duseithreads -Duseshrplib -Dprefix=/usr/local/perl5.28 && sudo make && sudo make install cd /usr/local/src/apache/mod_perl-2.0.10 sudo /usr/local/perl5.28/bin/perl Makefile.PL MP_APXS=/usr/bin/apxs sudo make && sudo make install #will install the module on top of the existing one case $OSID in amzn|rhel|fedora|centos) sudo systemctl restart httpd ;; sles) sudo systemctl restart apache2 #SUSE ;; ubuntu|debian) sudo service apache2 restart #Ubuntu ;; esac wget -q -O - http://localhost/cgi-bin/printenv |grep SERVER_SOFTWARE
The last line will print the Perl version. We can also open a browser and type the IP address from Step (4) of Web/middleware server for Perl. It should give a default page. Try the CGI path as well.
http://IPAddress/ http://IPAddress/cgi-bin/printenv http://IPAddress/cgi-perl/printenv
You can see three or four more variables for the same script run from mod_perl compared to mod_cgi. We will discuss this in detail in the next article. Till then, happy hacking with Perl on the cloud!