TODO : Read more documentation

It’s after bits like this one, I think I should spend more time reading documentation:



Create a new transaction.

This routine should _never_ be called by anything other than RT::Ticket. It should not be called from client code. Ever. Not ever. If you do this, we will hunt you down and break your kneecaps. Then the unpleasant stuff will start.

TODO: Document what gets passed to this

RT::Transaction->Create() developer manual for Request Tracker 4.2.

Best Practical RT training

I’ve spent the better part of Wednesday and Thursday of last week in Amsterdam, at Best Practical’s RT training sessions.

Best Practical

I’ve been using Request Tracker (RT) for many years now.   The first version I saw was 2.x, and it wasn’t my own install, but I did participate in configuration and customization.  I also used it on a daily basis.  That was love from the first sight.  The user interface seemed simple and straightforward (yes, it’s built by techies for techies), internal architecture seemed transparent, it was Open Source Software, and it was written in Perl.  What’s not to love?

Once I left that company, I think I’ve installed RT in pretty much every other company I worked for (there were a couple of exceptions, where the decision wasn’t my).  I’ve also done a couple of side projects, and I used it for my own needs too (going through all 3.x series and now jumping into 4.x).  And the more I used it, the more I loved it.   I even mentioned it in this blog a few times.  Have a look, for example, at this post from 2008, where I describe my toolbox and RT being one of the core tools in it.

For the past year or so, however, I was involved in a slightly different kind of work, while at a slightly different kind of environment.  Long story short, there was no RT and I missed it a lot.  That, though, gave me an opportunity to once again look around.  I was part of the team that researched and evaluated a variety of tools, which, functionally, are similar to what RT can do.  And the more I looked, the more I wanted RT.  Alas, the choice once again wasn’t mine.

That all made me a bit sad and nostalgic.  Why? Why – I was asking myself – can’t I get back to The Golden Times of Perl programming and using capable tools such as RT?  And I couldn’t find a good reason why not.  So, an idea seed was planted in my mind.  I thought about, and I thought more, and the idea grew.  And then I told a few people about it, and all of them seemed to like it, so I decided to pursue it.  Yet another side project, hopefully.  But the one which will be heavily based on RT.

Once the direction was chosen, the stars started to align.  One of the friends, who’s the part of the project, pointed out to me that Best Practical Solutions LLC – the company behind the Request Tracker – is doing a training session in Amsterdam.  Being a US-based company, their European training sessions are few and far apart, so I decided to go.

On one hand, I have to say that it is a bit expensive, especially for a self-funded trip.  On the other hand, it’s an Open Source tool and people who develop it do need to make money somehow, and training is one of the legitimate ways to do so.  On the same hand, I’ve been using the tool to save me countless hours, pulled out hair, and earn me quite a bit of cash in the process.  So it’s all fair.  I guess, it’s not that it’s pricey.  It’s more of me having a bit of a short time to decide, plan, and make it happen.  Anyways.  Was it worth it?

Learning new things about RT

It was!  Every bit so!  It was one of the best technical training sessions that I’ve been too, and I’ve been to a lot.  If I had to compare, I think it was the same level of quality I saw at Red Hat’s RHCE rapid track course.

Kevin Falcone, one of the RT architects and Best Practical’s senior engineers was the presenter.  We only had two days to cover everything, but he came prepared.  In fact, it’s a huge understatement.  He was simply top notch!  He had everything with him that was needed for the sessions – books, slides, notes, you name it.  He is also extremely knowledgeable about the RT’s past, present, and future, about who and how is using it, about what the community is doing, and about all those tiny little details all over the RT universe – from people, concepts and ideas, to bugs, configuration options, and branch names, both merged and not.  Also, while being very serious about his work,  Kevin was easy to talk to, and, what is probably even more surprising, he was also a keen listener, interested in what kind of problems or issues people are having with RT, where they are coming from, and so on.

As for the actual training sessions, I was a little bit worried to be bored out of my mind during the first day.  You see, the first day was mostly for RT users – new and seasoned.  While the second day was focused around more hardcore stuff like installation, configuration, customization, and development.

I’m happy to report, that my worries were baseless.  It turned out that even though I’ve been using RT for so long, I still have huge gaps in knowledge and understanding.  There were quite a few things I had no idea about, and there were a few that I knew about, but where an easier way exists, or my understanding wasn’t totally correct.

Here is an example of the knowledge bit that made quite a few people in the room go “Oh! Wow! Why didn’t I learn about it before?”.  In default (and many instances of non-default) configuration, RT would send an automatic email notification to the requester, upon the creation of a new ticket.  That’s a handy bit of functionality, served by a global scrip.  But, what happens if you have, say, 500 queues, and you don’t wan’t to sand such a notification for only two of those queues?  Until the training, I knew of two ways how to do it.  One involved removing the global scrip and re-creating a queue-level scrip only for those queues that needed to send the notification.  The other way would be to update the scrip code to check the current queue against a whitelist of queues.  Both would work, but neither one is elegant.  Well, apparently, there is a better, more elegant way, which also sheds some more light onto how RT “thinks”.  All you have to do is create a new queue-level AutoReply template with no body.  The same global scrip would execute, but would try to use the queue-level template, instead of the global one.  However, RT is being smart in a way, where there is nothing to send it won’t even try.  So an empty queue-level template would result in an email with no content, which RT simply won’t send out.  Brilliant, isn’t it?

But, as much as the first day was useful, the second day was a total blast.  We’ve covered a lot of ground (and had to move through the slides pretty fast at times), but that was like … like … like Neo learning kung fu in the Matrix movie: huge amounts of knowledge and wisdom just being uploaded straight into the brain.  I think one of the reasons that we could move so fast was due to everyone in the room having plenty of prior RT experience.  Everyone knew what Kevin was talking about, and there was instant insight and understanding.  Or so I think.

Some of the useful things that I’ve learned during the second day included:

  • the work with custom fields.  Creating, editing, searching (including saved searches), linking, and automatic population and extraction;
  • local installs and hacking.  Installing RT isn’t much of a deal for me at this stage, but knowing a simpler and faster way of just getting a local copy running for a bit hacking here and there – is always welcome;
  • initial data.  Something that is extremely useful for initializing new installs with queues, users, groups, custom fields, etc, as well as copying or automating batch operations of data input;
  • safe ways of doing and preserving local changes. I knew about RT extensions for a while now, but I could never bother enough to figure out how to do them myself.  Now I know.

Also, I’ve learned a great deal about RT’s roadmap for the upcoming version 4.2 and for the next probable version 4.4.

I have to say that the slide and training “program” wasn’t all that happened.  While we were sticking to the slides pretty close, Kevin made plenty of effort to focus more on the things which were interesting to people in the room, and to focus less on irrelevant bits and pieces.  A lot of questions were asked and answered – varying everywhere from localization to performance optimization and database tuning.

As I said before, Kevin is very knowledgeable about “what’s out there for RT”, so, as we joked in the room, the phrase of the day was: “there is a branch for that“.  Many a time that someone would ask for  specific piece of functionality or configuration, Kevin would say that there is a branch for that and then find an appropriate git branch in a matter of seconds.  Just to give you an indication of how tricky that is, consider the fact that there are currently 192 branches listed in RT’s GitHub repo.  (One of the most branched out project I manage at work has just over 20 branches, and I’m lost more times than there are days in a week.)

As far as technical questions go, I don’t think there was a single one that hasn’t been answered.  In fact, there were so many questions, that we kept asking way beyond the time allocated for the session, but Kevin stood his ground until each and every one of those puzzles wasn’t answered.

Oops.  That got lengthy all of a sudden.  I promise you that’s just an accident.  To wrap up, I have to say once again that it was an excellent experience, I’ve learned plenty, it was worth every single penny, and I strongly recommend the next sessions to anyone and everyone who is using RT.  I promise you, even if you think you know it all, you’ll learn plenty a new.


Request Tracker 4 released!

Here are some major technology news – Request Tracker 4 is released!  For those of you not in the know, Request Tracker is an open source ticketing system developed by the company called Best Practical Solutions LLC.  Request Tracker, or RT for short, is one of the most flexible pieces of software I’ve seen in my life.  It’s also an excellent example of software design and architecture for those who are into that.  I’ve used Request Tracker 3, the previous version, for anything from personal task and document management through to a large installation with a 100+ concurrent users and a 1,000,000+ tickets database.

New features in version 4, according the website, include the following:

  • Lifecycles
  • Mobile device interface
  • Branding and theme editor
  • Quote-folding in replies and comments
  • Articles integration based on RTFM
  • Easy full text search
  • Autocomplete of owners and requestors
  • Better HTML mail display
  • Easier and more efficient navigation menus
  • Refreshed ticket create and update pages
  • IP and Date/DateTime custom fields
  • Dropdown and radio list custom field display types
  • Finer-grain ticket-level control of notifications
  • Much improved rights management UI
  • Loads of performance improvements and bug fixes

Continue reading for the full text of the email sent to rt-announce mailing list.

Continue reading Request Tracker 4 released!

RT3 : Automatically assign owner by queue

There is one bit of functionality that I keep reusing for pretty much every installation of RT3 – automatic assignment of tickets to specific users based on queue.  There are a few solutions to this problem and some are documented in RT3 wiki.  But I always keep forgetting which solution to use and where I found it.  So, in hopes not to ever spend more than 3 seconds searching for such a solution, I’m posting it here.

We’ll be using a global scrip instead of a per-queue scrip.  This will simplify maintenance for those installations that use a lot of queues – you’ll need to change settings only in one place rather than all over the place.  Create the new global scrip with the following settings:

  • Description: AutoSetOwnerForQueue
  • Condition: On Create
  • Action: User Defined
  • Template: Global Template : Blank
  • Stage: TransactionCreate
  • Custom condition: return 1;
  • Custom action preparation code: return 1;
  • Custom action cleanup code:
my %owners = (
  'queue_name1' => 'username1',
  'queue_name2' => 'username1',
  'queue_name3' => 'username2',
my $QueueName = $self->TicketObj->QueueObj->Name;
return 1 unless defined($owners{$QueueName});
my $Actor = $self->TransactionObj->Creator;
return 1 if $Actor == $RT::SystemUser->id;
return 1 unless $self->TicketObj->Owner == $RT::Nobody->id;

my $MyUser = $owners{$QueueName};

$RT::Logger->info("Auto assigning ticket #". $self->TicketObj->id ." to user $MyUser" );
my ($status, $msg) = $self->TicketObj->SetOwner( $MyUser );
unless( $status ) {
  $RT::Logger->warning( "Impossible to assign the ticket to $MyUser: $msg" );
return undef;

Last time I’ve used this was on RT 3.8.8. Adjust accordingly for the earlier and later versions.

Integrating RT3 with Subversion

As I have mentioned a few times before, I am a big fan of using BestPractical RT3 for all sorts of things, including, but not limited to, bug tracking during project development.  I see a great benefit in having a single system for both technical support and development departments.  Bugs can be reported by customers, investigated by technical support department, passed on to developers, fixed and tested, and then passed back to technical support department to verify with the customer and resolve.

Needless to say, integrating RT3 with Subversion can be of great benefit.  In this case, not only you will have full history of bug reports, but you’ll also see which code changes were made for each bug report.  Learning from previous bug fixes and having a quick way to see why something was changed is priceless.

Read more to see how RT3 can be integrated with Subversion.  You can also easily adopt the same approach to other version control systems.

Continue reading Integrating RT3 with Subversion