Helpful Tips for Newbie System Admins

Before you start reading this tutorial, let me remind you once again who the intended audience of this post is — newbie system administrators. If you’re an experienced admin and are going to laugh at my naivete for writing such basic stuff, please go away — or provide some more ‘advanced’ tips in the comments below so that I know better for the future.

Anyway, let’s begin. If you’re like most newbie system admins, you run a windows system on your home PC / work laptop and connect to the servers you’re managing using putty. Everyone uses putty, you say. Well, yes but there are alternatives. One of the things I hate is to have to copy/paste all the usernames and passwords into that putty session before I can login. So, let’s get rid of that first.

Installing Jira with MySQL

Jira is an extremely well-known issue tracking system and is used widely for project management in a wide array of fields. It has quite a detailed documentation but it’s in the form of a wiki and as we all know, wikis are the worst way of creating software documentation. Anyway, in order to install Jira with MySQL, you will have to click and click and click. This tutorial aims to ease this issue by providing step-by-step instructions on how to install jira and enable it to connect with MySQL for storage. So let’s begin.

Note: These instructions are for the standalone version of Jira. You can use them quite easily for the WAR/EAR version but if you’re going on that route, you probably don’t need this article.

Ok, first download and install Java (I usually go with JDK) — version 6 is preferred. You can get the .bin file for Linux from java.sun.com (I refuse to call it Oracle Java). Make it executable and run it. JDK will be extracted in your current directory. Move it to /usr/share. Then set the JAVA_HOME variable.

[sourcecode lang=”bash”] JAVA_HOME=/usr/share/jdk1.6.0_23
export JAVA_HOME
[/sourcecode]

You might want to set this in your ~/.bash_profile file.

Next, create a user with which we will start jira — for security reasons.

[sourcecode lang=”bash”] sudo /usr/sbin/useradd –create-home –home-dir /usr/local/jira –shell /bin/bash jira
[/sourcecode]

Download and extract the jira standalone .tar.gz file to /usr/local/jira and change ownership of all the files to the jira user:

[sourcecode lang=”bash”] chown jira:jira /usr/local/jira -R
[/sourcecode]

Open port 8080 which is used by jira (by default) — edit the file /etc/sysconfig/iptables and enter the following rule:

[sourcecode lang=”bash”] -A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT
[/sourcecode]

Set the required jira.home property in the file /usr/local/jira/atlassian-jira/WEB-INF/classes/jira-application.properties

[sourcecode lang=”bash”] mkdir /usr/local/jira/jirahome
vi /usr/local/jira/atlassian-jira/WEB-INF/classes/jira-application.properties
# set the variable jira.home to /usr/local/jira/jirahome
[/sourcecode]

Restart the firewall and start jira using the following command:

[sourcecode lang=”bash”] sudo -u jira nohup /usr/local/jira/bin/catalina.sh run & > jira-nohup.log
[/sourcecode]

The use of sudo will run jira as the user jira and nohup will ensure that jira won’t stop running as soon as you close the shell. The output produced by the command will be saved to jira-nohup.log

Open the browser on location http://your.ip.add.ress:8080/ and ensure that you can see the jira setup page. Don’t bother proceeding with the setup because as soon as we connect jira to MySQL, this information will be lost. Let’s do that now.

Connecting with MySQL

Begin by stopping jira, installing mysql server, setting it to always start on system startup and starting the server.

[sourcecode lang=”bash”] /usr/local/jira/bin/shutdown.sh
yum install mysql mysql-server
chkconfig mysql on
service mysqld start
[/sourcecode]

Then start mysql, create a database and user for jira and assign all rights to the new user on the new database.

[sourcecode lang=”bash”] mysql
create database jiradb character set utf8;
grant all privileges on jiradb.* to jira@localhost identified by ‘[your new password]’;
q
[/sourcecode]

Now, edit the conf/server.xml in the jira directory and change the data source as follows:

[sourcecode lang=”bash”] <Resource name="jdbc/JiraDS" auth="Container" type="javax.sql.DataSource"
username="jira"
password="[jira user password]"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/jiradb?useUnicode=true&amp;characterEncoding=UTF8"
maxActive="20"
validationQuery="select 1"/>
[/sourcecode]

Note that the ampersand code in the connection string is not a formatting problem. It really has to say amp with an ampersand and a semicolon at either end.

Finally, edit the atlassian-jira/WEB-INF/classes/entityengine.xml file to set the final attribute:

[sourcecode lang=”bash”] <datasource name="defaultDS" field-type-name="mysql"
helper-class="org.ofbiz.core.entity.GenericHelperDAO"
check-on-start="true"
use-foreign-keys="false" …
[/sourcecode]

Delete the schema-name="PUBLIC" attribute immediately after the changed line to ensure that the database is populated properly.

Start jira once again and now you can enter the setup information. Open MySQL and ensure that jira is, in fact, using this engine.

Creating Multiple Volumes on Amazon EC2

For those of you who have used Amazon AWS (EC2 specifically) for more than just testing would know that the / partition in an AMI does not go beyond 10GB. So, if you need more space you need to mount more volumes. This is a beginner’s guide to do just that.

First off, create an AMI with EBS storage type and take a note of the zone in which that AMI sits. You can find this through the details pane in the ‘instances’ section of your AWS management console. Then, go over to the ‘volumes’ section and create a new volume.

Here, you need to make sure that you create the volume in the same zone as your AMI or you won’t be able to use the volume with it. Specify the capacity of the volume. That’s all that’s required at this stage. Click create and wait until the new volume becomes available. Then right-click on the volume and ‘Attach Volume’. Make sure you select the right instance and then specify the new device name. You can use something like ‘/dev/sdd’. Just use fdisk -l in your running instance to make sure it’s not already in use.

After that, login to your AMI and fdisk -l again to make sure that the new volume is available. Now, you need to create a partition and format it for linux to use. Then, mount it someplace. Here we’re going to move the whole /var to this new partition so that our logs etc can have more free space to grow.

[sourcecode lang=”bash”] mkfs.ext3 /dev/sdd
mkdir /mnt/var
mount /dev/sdd /mnt/var
cp -R /var/* /mnt/var
touch /mnt/var/new-vol
[/sourcecode]

The last line is there to verify after boot that you are indeed using the newly volume. You can also use df -h after reboot to test this but I just feel better this way.

Finally, open up the /etc/fstab file and enter the new device /dev/sdd and the mount point /var.

[sourcecode lang=”bash”] /dev/sdd /var ext3 defaults 0 0
[/sourcecode]

And reboot.

Bash Script to Find and Replace in a Set of Files

Ok, so this might sound childish to the more experienced admins and programmers but I’ve always found the need to search and replace a string in multiple files. For example, if I have to work with an inexperienced programmer’s code, I might have to change the name of the database in a couple of dozen places. If you are in such a place, you might want to try the following script:

[sourcecode lang=”bash”] for f in submit_*;
do sed "s/old_db_name/new_db_name/" < $f > a_$f ;
mv a_$f $f ;
done
[/sourcecode]

The first line finds all files that match the pattern submit_*. The loop first calls sed, makes the replacement and outputs the file to a_$f. Finally, it renames the a_$f file to $f so that we get the original filename. So, there you go. You can make all sorts of complicated finds and replaces through regular expressions and unleash the power of sed on this script. Chao.

Troubleshooting vTiger CRM Install on PHP 5.2

I recently had to deploy vTiger CRM 5 on a machine running PHP 5.2. Turned out that vTiger does not like PHP 5.2 because of some differences between PHP 5.0 and 5.2. As soon as you start the install script, you get the following error:

[sourcecode lang=”bash”] Cannot redeclare class DateTime
[/sourcecode]

The problem is that vTiger defines its own DateTime class and so does PHP 5.2. The solution therefore (see vTiger wiki) was to rename the class in vTiger source. To do that, all you need to do is to run the following commands from the vtiger source root (e.g. /var/www/html/vtiger):

[sourcecode lang=”bash”] mv modules/Calendar/Date.php modules/Calendar/Date.php.back
sed s/ DateTime/ com_vtiger_DateTime/ < modules/Calendar/Date.php.back > modules/Calendar/Date.php
mv modules/Calendar/Appointment.php modules/Calendar/Appointment.php.back
sed s/ DateTime/ com_vtiger_DateTime/ < modules/Calendar/Appointment.php.back > modules/Calendar/Appointment.php
mv include/utils/RecurringType.php include/utils/RecurringType.php.back
sed s/ DateTime/ com_vtiger_DateTime/ < include/utils/RecurringType.php.back > include/utils/RecurringType.php
[/sourcecode]

This script modifies the files Date.php, Appointment.php and RecurringType.php by first taking the backup of the file and then replacing all occurrences of ” DateTime” with ” com_vtiger_DateTime”. The backup is kept in the same location.

After that, you can run the install script and get to the login screen. When you login, you get a new error (something to this effect):

[sourcecode] Catchable fatal error: Object of class <ClassName> could not be converted to string in /var/www/xxx on line yyy
[/sourcecode]

The solution of this came from this great post. You need to create a custom error handler (called ErrorHandler.php) in the vtiger source root with the following content:

[sourcecode lang=”php”] <?php
function compatibilityErrorHandler($errno, $errstr, $errfile, $errline)
{
switch ($errno) {
case  E_RECOVERABLE_ERROR:
break;
default:
echo "Unknown error type: [$errno] $errstr n";
break;
}
}

// set to the user defined error handler
$old_error_handler = set_error_handler("compatibilityErrorHandler", E_RECOVERABLE_ERROR);
?>
[/sourcecode]

Finally, you need to include this error handler through the config.inc.php. For that, execute the following commands:

[sourcecode lang=”bash”] mv config.inc.php config.inc.php.back
sed "/include(‘vtigerversion.php’);/ a
require_once(‘ErrorHandler.php’);" < config.inc.php.back > config.inc.php
[/sourcecode]

Notice the line break after the a. The first command makes a backup. The second inserts the require_once directive after the line with the include directive.

Web Fax for Asterisk

Over the past few weeks, I have been working with the popular telephony software asterisk and all the stack that stands on top of it. I have (in coordination with a friend) setup asterisk, FreePBX, a2billing, fax for asterisk and vicidial on several production servers. Combined, these provide a complete telephony solution for a wide range of commercial organizations. As a side note, I might be writing tutorials about some of these things in the future.

One of most problematic of these technologies was getting fax to work with asterisk. We tried many variations and finally found out that Digium’s Fax for Asterisk, or Free Fax for Asterisk (FFA) is currently the most stable and easy to set up. However, it does not provide an easy way to let your end users send faxes if they don’t have SIP enabled fax machines. What’s more, there is no software available that would allow you to do that! So, in one of our projects, we had to come up with a custom interface and we decided to open it up so that many others who need it can benefit from our efforts and hopefully build on it.

We call this PHP-based script Web Fax for Asterisk and are releasing it under GPLv3. For those of you who just want to get the code, you can get it from sourceforge.net. You can also get it from the SF SVN repo if you want to contribute. (In that case, gimme a shout and I’ll allow you to commit.)

For those of you who want to learn how it’s made, please read on.

Auto Scale with Amazon Elastic Compute Cloud (EC2)

In this video, we talk about Auto Scale feature of the Elastic Compute Cloud (EC2). Auto Scale allows AWS to automatically start new instances of AMIs as more and more load is put on the instance. You can define triggers (policies) that define what the low and high limits are. Whenever these limits are breached, instances can be started or stopped depending on the policies. In this video, we start from scratch and setup the Auto Scale feature.

All comments are welcome.

Getting Started with Amazon EC2 – Install, Configure, Connect

The second in the series of Amazon Web Service tutorial videos. Here we describe how to create a keypair for shell access to an Amazon Machine Image instance, how to do basic firewall configuration to enable remote login and finally start and connect to the a basic Amazon Linux AMI.

All comments and questions would be most welcome.

Produced by: Mohammad Nauman (voice) and Toqeer Ali

Inserting Source Code and LaTeX in WordPress

A friend of mine asked me the other day how ‘pretty printed’ source code can be inserted into wordpress posts. Here’s how:

If you have a self-hosted wordpress server, get the plugin ‘SyntaxHighlighter Evolved’. Defaults work fine. If you have a wordpress.com account, the plugin is already. For LaTeX, you need the ‘WP-Latex’ plugin. After that, you can insert the source code using the syntax

[sourcecode language=”bash”] [ sourcecode language="lang" ] … code here (there is no space after the [ in the lines above and below).
[ / sourcecode] [/sourcecode]

You can get a list of supported languages here. Latex code can be inserted using the syntax:

[sourcecode language=”bash”] $ latex 2^x $
[/sourcecode]

Again, no space after the $ in the above code. There you go!