Packaging Code#
To distribute your modules, the changes must first be packaged in the .opm
format before it can be listed in a repository or installed.
Note
An exception is during development when using the module tools.
A specification file or .sopm
is the basis for compiling a package from your source directory. This includes the properties, restrictions, and files of the module.
Package Specification File#
Packages are simply XML files with encoded instructions, as are the specification files. Create or edit your .sopm
in the editor of choice. The package metadata, list of files, and the database options are just a few things described by the SOPM.
Element List#
XML Element |
Example |
Description |
Required |
---|---|---|---|
Name |
Calendar |
Name of package |
Yes |
Version |
1.2.3 |
Version of Package |
Yes |
Framework |
6.2.x |
Version of Framework. This tag can be used multiple times and dictates the minimum framework level. |
Yes |
Vendor |
Znuny GmbH |
Name of Vendor |
Yes |
URL |
Vendor URL |
Yes |
|
License |
GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 |
The license of the package. |
Yes |
ChangeLog
|
Added some feature.
|
The package change log (optional). The tag requires a version and date attribute. Can be used multiple times.
<ChangeLog Version="1.1.1" Date="2013-02-15 16:17:51">New package.</ChangeLog> |
No
|
Description
|
A web calendar.
|
The sort description of the package. Can be used multiple times for packages in different languages.
<Description Lang="de">Ein Web Kalender.</Description> <Description Lang="en">A web calendar.</Description> |
Yes
|
PackageIsVisible |
1 |
If set, the package cannot be seen in the package manager. |
No |
PackageIsDownloadable |
0 |
If set, the package cannot be downloaded in the front-end. |
No |
PackageIsRemovable |
1 |
If set, the package may be removed from the system. |
No |
BuildHost |
host.example.com |
Automatically filled during creation. |
Yes |
BuildDate |
2022-01-01 |
Automatically filled during creation. |
Yes |
PackageRequired
|
Package Name
|
Describes dependencies including versions. Can be used multiple times. Requires a Version attribute.
<PackageRequired Version="1.0.3">SomeOtherPackage</PackageRequired> |
No
|
ModuleRequired |
MIME::Tools |
Perl modules that must be installed beforehand (optional). |
No |
OS |
linux |
Possible options are linux, darwin, mswin32. Defines operating system requirements, if needed. |
No |
Filelist
|
<File Permission="644" Location="Kernel/Config/Files/Calendar.pm"/> <File Permission="644" Location="Kernel/Modules/AgentCalendar.pm"/> |
This is a list of files included in the package. Self-closed tag. Can be used multiple time and requires a Permission and Location attribute.
|
No
|
DatabaseInstall |
see example |
Database commands to be executed during install. See if attributes. |
No |
DatabaseUpgrade |
see example |
Database commands to be executed during upgrade. See if attributes. |
No |
DatabaseReinstall |
see example |
Database commands to be executed during re-installation. See if attributes. |
No |
DatabaseUninstall |
see example |
Database commands to be executed during removal. See if attributes. |
No |
IntroInstall |
|
To show a “pre” or “post” install introduction in installation dialog. Can be used multiple times for extra languages. |
No |
IntroUninstall |
|
To show a “pre” or “post” uninstall introduction in uninstallation dialog. |
No |
IntroReinstall |
|
To show a “pre” or “post” reinstall introduction in re-installation dialog. |
No |
IntroUpgrade |
|
To show a “pre” or “post” upgrade introduction in upgrading dialog. |
No |
CodeInstall |
see example |
Code to be executed during installation. See if attributes. |
No |
CodeUninstall |
see example |
Code to be executed during removal. See if attributes. |
No |
CodeReinstall |
see example |
Code to be executed during re-installation. See if attributes. |
No |
CodeUpgrade |
see example |
Code to be executed during upgrade. See if attributes. |
No |
PackageMerge
|
<PackageMerge Name="MergeOne" TargetVersion="2.0.0"></PackageMerge> |
This tag singals that a package has been merged into another package. In this case the original package needs to be removed from the file system and the packages database, but all data must be kept.
Let’s assume that
PackageOne was merged into PackageTwo . Then PackageTwo.sopm should contain this.See notes below
|
No
|
SQL Examples#
Example SQL Install:
<DatabaseInstall>
<TableCreate Name="calendar_event">
<Column Name="id" Required="true" PrimaryKey="true" AutoIncrement="true" Type="BIGINT"/>
<Column Name="title" Required="true" Size="250" Type="VARCHAR"/>
<Column Name="content" Required="false" Size="250" Type="VARCHAR"/>
<Column Name="start_time" Required="true" Type="DATE"/>
<Column Name="end_time" Required="true" Type="DATE"/>
<Column Name="owner_id" Required="true" Type="INTEGER"/>
<Column Name="event_status" Required="true" Size="50" Type="VARCHAR"/>
</TableCreate>
</DatabaseInstall>
Example SQL Update
<DatabaseUpgrade>
<TableCreate Name="calendar_event_involved" Version="1.3.4">
<Column Name="event_id" Required="true" Type="BIGINT"/>
<Column Name="user_id" Required="true" Type="INTEGER"/>
</TableCreate>
</DatabaseUpgrade>
Example SQL Reinstall
<DatabaseReinstall></DatabaseReinstall>
Example SQL Uninstall
<DatabaseUninstall>
<TableDrop Name="calendar_event" />
</DatabaseUninstall>
Note
You also can choose <Database* Type="post">
or <Database* Type="pre">
to define the time of execution separately (post
is default).
For more info see package life cycle. Information on which actions have to be performed in case of an upgrade (optional).
Example if already installed package version is below 1.3.4 (e. g. 1.2.6), the defined action will be performed:
Introduction Texts#
Package Texts
For some tags it’s possible to use HTML formatted texts. You can also use the Format
attribute to define if you want to use “html” (which is default) or “plain” to use automatically a <pre></pre>
tag when text is shown (to keep the newlines and whitespace of the content).
Helper Code Examples#
Code Installation Example
It may be necessarry to execute perl code upon installation. Add this tag to your SOPM.
<CodeInstall><![CDATA[
# log example
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'notice',
Message => "Some Message!",
);
# database example
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => "SOME SQL");
]]></CodeInstall>
Code Uninstallation Example
It may be necessary to execute perl code upon installation. Add this tag to your SOPM.
<CodeUninstall><![CDATA[
# log example
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'notice',
Message => "Some Message!",
);
# database example
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => "SOME SQL");
]]></CodeUninstall>
Code Reinstall Example
It may be necessary to execute perl code upon installation. Add this tag to your SOPM.
<CodeReinstall><![CDATA[
# log example
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'notice',
Message => "Some Message!",
);
# database example
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => "SOME SQL");
]]></CodeReinstall>
Code Upgrade Example
It may be necessary to execute perl code upon installation. Add this tag to your SOPM.
<CodeUpgrade><![CDATA[
# log example
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'notice',
Message => "Some Message!",
);
# database example
$Kernel::OM->Get('Kernel::System::DB')->Do(SQL => "SOME SQL");
]]></CodeUpgrade>
Note
You also can choose <Code* Type="post">
or <Code* Type="pre">
to define the time of execution separately (post
is default).
For more info see Package Life Cycle. Perl code to be executed when the package is upgraded (subject to version
tag), (optional). Example if already installed package version is below 1.3.4 (e. g. 1.2.6), defined action will be performed.
Merging Packages#
Code Merging Notes
Additionally it is possible to add required database and code upgrade tags for PackageOne
to make sure that it gets properly upgraded to the TargetVersion
before merging it - to avoid inconsistency problems. Here’s how this could look like:
<PackageMerge Name="MergeOne" TargetVersion="2.0.0">
<DatabaseUpgrade Type="merge">
<TableCreate Name="merge_package">
<Column Name="id" Required="true" PrimaryKey="true" AutoIncrement="true" Type="INTEGER"/>
<Column Name="description" Required="true" Size="200" Type="VARCHAR"/>
</TableCreate>
</DatabaseUpgrade>
</PackageMerge>
As you can see the attribute Type="merge"
needs to be set in this case. These sections will only be executed if a package merge is possible.
Conditions: IfPackage
and IfNotPackage
#
These attributes can be added to the regular Database*
and Code*
sections. If they are present, the section will only be executed if another package is or is not in the local package repository.
<DatabaseInstall IfPackage="AnyPackage">
...
</DatabaseInstall>
<CodeUpgrade IfNotPackage="OtherPackage">
...
</CodeUpgrade>
These attributes can be also set in the ``Database*`` and
``Code*`` sections inside the ``PackageMerge`` tags.
Example Source File#
This is an example spec file looks with some of the above tags.
<?xml version="1.0" encoding="utf-8" ?>
<otrs_package version="1.0">
<Name>Calendar</Name>
<Version>0.0.1</Version>
<Framework>3.2.x</Framework>
<Vendor>OTRS AG</Vendor>
<URL>https://otrs.com/</URL>
<License>GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007</License>
<ChangeLog Version="1.1.2" Date="2013-02-15 18:45:21">Added some feature.</ChangeLog>
<ChangeLog Version="1.1.1" Date="2013-02-15 16:17:51">New package.</ChangeLog>
<Description Lang="en">A web calendar.</Description>
<Description Lang="de">Ein Web Kalender.</Description>
<IntroInstall Type="post" Lang="en" Title="Thank you!">Thank you for choosing the Calendar module.</IntroInstall>
<IntroInstall Type="post" Lang="de" Title="Vielen Dank!">Vielen Dank fuer die Auswahl des Kalender Modules.</IntroInstall>
<BuildDate>?</BuildDate>
<BuildHost>?</BuildHost>
<Filelist>
<File Permission="644" Location="Kernel/Config/Files/Calendar.pm"></File>
<File Permission="644" Location="Kernel/System/CalendarEvent.pm"></File>
<File Permission="644" Location="Kernel/Modules/AgentCalendar.pm"></File>
<File Permission="644" Location="Kernel/Language/de_AgentCalendar.pm"></File>
<File Permission="644" Location="Kernel/Output/HTML/Standard/AgentCalendar.tt"></File>
<File Permission="644" Location="Kernel/Output/HTML/NotificationCalendar.pm"></File>
<File Permission="644" Location="var/httpd/htdocs/images/Standard/calendar.png"></File>
</Filelist>
<DatabaseInstall>
<TableCreate Name="calendar_event">
<Column Name="id" Required="true" PrimaryKey="true" AutoIncrement="true" Type="BIGINT"/>
<Column Name="title" Required="true" Size="250" Type="VARCHAR"/>
<Column Name="content" Required="false" Size="250" Type="VARCHAR"/>
<Column Name="start_time" Required="true" Type="DATE"/>
<Column Name="end_time" Required="true" Type="DATE"/>
<Column Name="owner_id" Required="true" Type="INTEGER"/>
<Column Name="event_status" Required="true" Size="50" Type="VARCHAR"/>
</TableCreate>
</DatabaseInstall>
<DatabaseUninstall>
<TableDrop Name="calendar_event"/>
</DatabaseUninstall>
</otrs_package>
Build Package#
To build a package from the specification file, do the following.
shell> bin/otrs.Console.pl Dev::Package::Build /path/to/example.sopm /tmp
Building package...
Done.
Package Life Cycle#
Install/Upgrade/Uninstall#
The following image shows you how the life cycle of a package installation/upgrade/un-installation works in the backend step by step.
graph LR subgraph Package Life Cycle A[OS, Framework, Package, Modules] B[Code Execution] C[Database Processing] D[File Processing] E[Database Execution] F[Code Processing] subgraph Check Process A end subgraph Pre A --> B --> C end subgraph Processing C --> D end subgraph Post D --> E --> F end end