A Perl Helpdesk You Can Still Extend: OTOBO Packages on Open ITSM Hub
A Perl Helpdesk You Can Still Extend: OTOBO Packages on Open ITSM Hub
A lot of production Perl is invisible. It answers mail, opens tickets, and keeps a queue moving while the public conversation has moved on to other languages. OTOBO is one of the systems still doing that work in Perl, and it still expects new behaviour to arrive as Perl modules inside a package.
Open ITSM Hub lists those packages in one place. The OTOBO slice of the catalog is OTOBO packages on Open ITSM Hub. This article is about the Perl those packages are written in: the object manager, the .sopm spec, and the .opm file an administrator installs.
Why this codebase is still Perl
OTOBO is a web-based ticket system for a help desk and for IT service management. It continues the OTRS Community Edition line. The application lives under Kernel/. Business logic is Perl modules. Agent screens are Perl modules. Translations are Perl modules that return a hash. Templates are Template Toolkit (.tt), which Perl has used for this job for a long time.
The OTOBO 11 developer guide describes the layout in plain terms. Kernel/System/ holds core modules such as Kernel::System::Ticket, Kernel::System::User, Kernel::System::DB, and Kernel::System::Log. Kernel/Modules/ holds front-end modules such as a queue view. Kernel/Language/ holds translation files. Kernel/Output/HTML/ holds templates. Command-line tools are .pl scripts. The web entry points are still Perl.
That split is the part a Perl programmer should notice. A screen does not talk to the database by itself. A front-end module gets a system object and calls it. The same system object is what a console command, a scheduler task, and a Generic Interface operation use.
The object manager is the API
Code inside OTOBO does not construct core services with a long new() chain. It asks the object manager:
```perl my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket'); my $LogObject = $Kernel::OM->Get('Kernel::System::Log');
$LogObject->Log( Priority => 'notice', Message => 'Package install reached the ticket layer.', ); ```
Kernel::OM->Get returns the shared instance for that class name. The string is the contract. A package that needs logging, configuration, or the database names Kernel::System::Log, Kernel::System::Config, or Kernel::System::DB and receives the object the rest of the process already uses.
Front-end modules follow a smaller public surface. The developer guide states that a front-end module exposes new() and run(), and that the front-end handle (index.pl and its relatives) is what calls them. run() returns the HTML for that request. If you have maintained a CGI-era Perl application, the shape is familiar: one process-wide kernel, one module per action, one method that renders the page.
A package is an XML spec plus Perl files
Administrators do not copy .pm files into the tree by hand. They install an OPM package (.opm). You produce that file from a spec (.sopm). The spec is XML. The OTOBO 11 package-building chapter is the reference for the elements below.
A small spec names the package, the framework series it targets, the vendor, the licence, and the files to copy:
xml
<?xml version="1.0" encoding="utf-8" ?>
<otobo_package version="1.0">
<Name>Calendar</Name>
<Version>0.0.1</Version>
<Framework>11.0.x</Framework>
<Vendor>Example</Vendor>
<URL>https://example.com/</URL>
<License>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</License>
<Description Lang="en">A calendar module.</Description>
<Filelist>
<File Permission="644" Location="Kernel/System/CalendarEvent.pm"/>
<File Permission="644" Location="Kernel/Modules/AgentCalendar.pm"/>
<File Permission="644" Location="Kernel/Language/en_AgentCalendar.pm"/>
</Filelist>
</otobo_package>
Framework is a compatibility claim (11.0.x in current docs). Filelist is the install set. Permissions are explicit because the package manager writes the files into the OTOBO home.
Build the archive with the console command documented for OTOBO 11:
text
bin/otobo.Console.pl Dev::Package::Build /path/to/example.sopm /tmp
The result is example-0.0.1.opm in the output directory. That file is what Package Manager installs.
What the spec can demand of Perl and of the database
The same XML file can declare dependencies that a CPAN-minded reader will recognise.
ModuleRequired names Perl modules that must already be installed, with a version:
xml
<ModuleRequired Version="1.03">Encode</ModuleRequired>
<ModuleRequired Version="5.32">MIME::Tools</ModuleRequired>
PackageRequired names another OTOBO package. OS restricts the install to linux, darwin, or mswin32. None of this is a new packaging invention. It is a manifest: CPAN-level modules, sibling packages, and operating systems, checked before files are copied.
CodeInstall and CodeUninstall are Perl, wrapped in CDATA, executed by the package manager. The documented pattern uses the object manager rather than a private database handle:
perl
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'notice',
Message => 'Some Message!',
);
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => 'SOME SQL');
Schema changes belong in DatabaseInstall / DatabaseUninstall (TableCreate, Insert, and the matching drop). The guide also allows intro text, per language, shown before or after install. The code hooks are the part that matters to a Perl author: install-time Perl runs inside the application, with the same objects as runtime code.
Kernel::System::Package is the module that performs this lifecycle (read a package, install it, uninstall it). Extensions call it through $Kernel::OM->Get('Kernel::System::Package') like any other core service.
Where the files go
| Path under the OTOBO home | Perl role |
| ------------------------------- | ---------------------------------------------------- |
| Kernel/System/*.pm | Domain logic: tickets, users, mail, your new service |
| Kernel/Modules/*.pm | Front-end controllers with new and run |
| Kernel/Language/*_*.pm | Translation hashes |
| Kernel/Config/Files/XML/*.xml | Registration of modules, menus, and settings |
| Kernel/Output/HTML/**/*.tt | Template Toolkit views |
| *.sopm | Package spec, kept in your source tree |
| *.opm | Built package, installed by Package Manager |
A typical extension therefore contains one system class, one agent module, one template, one language file, and an XML config file that tells OTOBO the module exists. The spec’s Filelist is the only list the installer trusts.
Generic Interface code, for integrations, follows the same rule. Transports live under Kernel/GenericInterface/Transport/, operations under Kernel/GenericInterface/Operation/. A SOAP-over-HTTP transport is a Perl module on that path, shipped inside an .opm like any other file in the list.
Reading the catalog as a Perl developer
The OTOBO list on Open ITSM Hub is a directory of plugins, integrations, and tools for this system. Open the entry you care about and look for three Perl questions before you install anything.
- Which
Frameworkversions the.sopmclaims. - Which
ModuleRequiredentries you would have to provide from CPAN or from the OS package set. - Whether the interesting behaviour is a
Kernel::System::*class you can call from your own module, or only a front-end screen.
Znuny is the other active fork of the same Perl tree, with the same package idea. Zammad is a different helpdesk written in Ruby; a Ruby gem or a PHP client on a mixed catalog is not an OTOBO .opm. Filter for OTOBO when you want Perl packages.
Practical limits
An .opm runs with the permissions of the OTOBO process and can ship CodeInstall that talks to the database. Treat a package the way you treat a CPAN module from an author you do not know: read the spec, read the .pm files, and install on a copy of the system first.
Framework is a declared constraint, not a test suite. A package marked for an older series may load on a newer one, or it may call a method that moved. The developer guide’s package chapter and the module’s own changelog are the documents that tell you which.
Patches against core files are a bad fit for this format. The supported extension point is new files under Kernel/, registered in XML, built into an .opm. That is how local behaviour survives an upgrade.
What to take back to your own code
OTOBO shows a durable Perl application shape: a kernel of system classes, thin front-end modules, Template Toolkit for HTML, and a single object manager so that application code depends on names instead of constructors. Packaging is XML plus those files, with CPAN modules declared beside the file list, and optional Perl that runs on install and uninstall.
If you maintain sites on this stack, start from the OTOBO package list on Open ITSM Hub, then read the .sopm the way you would read a META.json: name, version, framework, required modules, and the Perl you are about to run.
Sources
- OTOBO 11 developer guide, architecture: https://doc.otobo.org/manual/dev/11.0/en/content/get-started/architecture.html
- OTOBO 11 developer guide, package building: https://doc.otobo.org/manual/dev/11.0/en/content/how-to-publish-otobo-extensions/package-building.html
Leave a comment