Difference between revisions of "SME Server:Documentation:Developers Manual:Chapter13"
m (Protected "SME Server:Documentation:Developers Manual:Chapter13": documentation control [edit=sysop:move=sysop]) |
|||
(4 intermediate revisions by 2 users not shown) | |||
Line 48: | Line 48: | ||
===Setting up your RPM development environment=== | ===Setting up your RPM development environment=== | ||
− | + | {{Outdated}} | |
If you haven't done so already, set up an RPM development environment. If you are using an SME Server as your development environment, you will need to alter your user account to enable regular login. If you want to enable account "joe", then you would type the following commands from the root account: | If you haven't done so already, set up an RPM development environment. If you are using an SME Server as your development environment, you will need to alter your user account to enable regular login. If you want to enable account "joe", then you would type the following commands from the root account: | ||
Line 54: | Line 54: | ||
db accounts setprop joe Shell /bin/bash | db accounts setprop joe Shell /bin/bash | ||
− | + | {{Note box|msg=Shell/login access is disabled by default to enhance the security of the SME Server. Shell access should only be provided to users who require it and who can be trusted to maintain system security.}} | |
− | |||
− | |||
− | |||
− | |||
− | |||
Then you should be able to log in to the server as user "joe", and get a Linux command line prompt. Log in, then type the following commands to set up your RPM work area: | Then you should be able to log in to the server as user "joe", and get a Linux command line prompt. Log in, then type the following commands to set up your RPM work area: | ||
Line 101: | Line 96: | ||
===Building an RPM=== | ===Building an RPM=== | ||
+ | {{Outdated}} | ||
+ | This section describes the process for building an RPM - step by step. | ||
− | + | Choose a name and version number for your package. We are going to package the complete loggerdemo example and will use <var class="LITERAL">loggerdemo</var> and <var class="LITERAL">1.0.0</var> as the name and version number. | |
+ | |||
+ | Collect all of the files which have been created in the previous sections into the <tt class="FILENAME">/tmp/</tt> directory. There is one additional file <tt class="FILENAME">createlinks</tt> which looks like this: | ||
− | + | #!/usr/bin/perl -w | |
− | |||
use esmith::Build::CreateLinks qw(:all); | use esmith::Build::CreateLinks qw(:all); | ||
Line 114: | Line 112: | ||
panel_link("loggerdemo", $panel); | panel_link("loggerdemo", $panel); | ||
− | + | Create the directory hierarchy required for building the RPM. This is very close to the hierarchy on the installed system. | |
− | + | ||
+ | # Change to the SOURCES directory | ||
cd ~/rpms/SOURCES | cd ~/rpms/SOURCES | ||
Line 142: | Line 141: | ||
# The createlinks auxiliary file | # The createlinks auxiliary file | ||
− | cp -p /tmp/createlinks . | + | cp -p /tmp/createlinks . |
+ | |||
+ | # The DB fragments should be created as files | ||
+ | mkdir -p root/etc/e-smith/db/configuration/defaults/loggerdemo | ||
+ | echo "service" > !$/type | ||
+ | echo "enabled" > !$/status | ||
+ | echo "10" > !$/Interval | ||
+ | |||
+ | Your directory structure should now look like this: | ||
+ | |||
+ | [gordonr@sevendev1 loggerdemo-1.0.0]$ find . -type f | ||
./root/etc/e-smith/templates/etc/crontab/25templatedemo | ./root/etc/e-smith/templates/etc/crontab/25templatedemo | ||
./root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/loggerdemo | ./root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/loggerdemo | ||
./root/etc/e-smith/web/functions/loggerdemo | ./root/etc/e-smith/web/functions/loggerdemo | ||
./root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel/loggerdemo.pm | ./root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel/loggerdemo.pm | ||
+ | ./root/etc/e-smith/db/configuration/defaults/loggerdemo/{type|status|Interval} | ||
./createlinks | ./createlinks | ||
− | + | ||
+ | Package the directory into a tarball: cd ~/rpms/SOURCES | ||
tar zcvf loggerdemo-1.0.0.tar.gz loggerdemo-1.0.0 | tar zcvf loggerdemo-1.0.0.tar.gz loggerdemo-1.0.0 | ||
− | + | ||
− | %define name loggerdemo | + | Create the RPM specification "SPEC" file <tt class="FILENAME">~/rpms/SPECS/loggerdemo.spec</tt> which looks like this: |
+ | |||
+ | %define name loggerdemo | ||
%define version 1.0.0 | %define version 1.0.0 | ||
%define release 01 | %define release 01 | ||
Line 179: | Line 192: | ||
%build | %build | ||
perl createlinks | perl createlinks | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
%install | %install | ||
Line 198: | Line 203: | ||
%post | %post | ||
− | |||
− | |||
/sbin/e-smith/expand-template /etc/crontab | /sbin/e-smith/expand-template /etc/crontab | ||
true | true | ||
Line 210: | Line 213: | ||
%defattr(-,root,root) | %defattr(-,root,root) | ||
− | + | ||
− | + | Note the <var class="LITERAL">%post</var> (post-installation) and <var class="LITERAL">%postun</var> (post-uninstallation) statements which expand the <tt class="FILENAME">/etc/crontab</tt> template after installing or uninstalling the RPM. | |
− | rpmbuild -bp loggerdemo. | + | |
− | + | Check that your RPM will build OK with "build prepare": | |
− | + | cd ~/rpms/SPECS | |
− | + | rpmbuild -bp loggerdemo.spec | |
− | + | ||
+ | The last line of output should be <var class="LITERAL">+ exit 0</var> if rpmbuild is successful. | ||
+ | |||
+ | Run the '''rpmbuild''' command again to actually create your RPM with the "build all" options: | ||
+ | rpmbuild -ba loggerdemo.spec | ||
+ | |||
+ | If everything was successful, the last line of output should again be <var class="LITERAL">+ exit 0</var>. | ||
+ | |||
+ | The RPMs should have been generated and put into <tt class="FILENAME">~/rpms/RPMS/noarch/</tt> as this program can run equally well on any platform. A source RPM should also exist in <tt class="FILENAME">~/rpms/SRPMS/</tt>. | ||
+ | |||
+ | Test your RPM by installing it on an SME Server test box. | ||
+ | {{Note box|msg=RPMs need to be installed as <var class="LITERAL">root</var>, but you should not log in as the root user. Instead, you should create a normal user and provide them with 'root' privileges via the '''sudo''' command. To provide full <span class="emphasis">''sudo''</span> rights to the user <var class="LITERAL">joe</var>, use the '''su - -c /usr/sbin/visudo''' and add the following line to the end of the file: joe ALL=(ALL) ALLYou can then use the '''sudo''' to run commands as <var class="LITERAL">root</var> when required. You will be prompted for your password (not the root password) which ensures that someone else isn't using your terminal.}} | ||
+ | |||
+ | sudo yum localinstall ~/rpms/RPMS/noarch/loggerdemo-1.0.0-01.noarch.rpm | ||
Preparing... ########################################### [100%] | Preparing... ########################################### [100%] | ||
1:loggerdemo ########################################### [100%] | 1:loggerdemo ########################################### [100%] | ||
Line 230: | Line 246: | ||
Migrating existing database backups | Migrating existing database backups | ||
Migrating existing database yum_available | Migrating existing database yum_available | ||
− | Migrating existing database domains | + | Migrating existing database domains |
− | sudo rpm -e loggerdemo | + | |
+ | The customization should be fully installed, and the <tt class="FILENAME">/etc/crontab</tt> file should show the customization. | ||
+ | |||
+ | Then remove the customization: | ||
+ | sudo rpm -e loggerdemo | ||
+ | |||
+ | The customization should be completely gone, and the <tt class="FILENAME">/etc/crontab</tt> file should look the way it did before. | ||
<div class="SECT2"> | <div class="SECT2"> |
Latest revision as of 00:07, 27 November 2008
Packaging your application
Once you have created a customization for your SME Server by adding new files, directories, and symbolic links (for your actions, events, etc.) - and perhaps also triggering an action to initialize your customization - you are ready to package your customization into an RPM.
A quick introduction to RPMs
All SME Server software packages are distributed as RPM packages. This is the format used by CentOS and other major Linux distributions for distributing applications and other collections of files. The RPM system provides the ability to install, upgrade, remove and (importantly) verify the contents of installed packages.
An RPM essentially consists of an archive of all the files required by a piece of software. Additionally, it includes meta-information describing the software, and scripts which must be run to install or uninstall the software.
Meta-information stored in an RPM includes:
- summary and description of the software
- package name
- version number
- copyright information
- category/group to which the software belongs
- name and email address of the packager
- pre-requisites to installing this package
- ... and more
Selecting and creating RPMs for your application
Your application will typically depend on several components:
- Software packages that are shipped as a standard part of the SME Server. You do not need to include any of these packages; they are always present in the runtime environment.
- Software packages that are not a standard part of the SME Server, but that are required by your software, and would also be of general use in the runtime environment. For example: a Java runtime environment, libraries that enable communication with devices, etc. If possible, these packages should be made into separate packages, rather than being included in your application. This makes it easier to share them with other applications and enforces version compatiblity.
- Software packages that are not a standard part of the SME Server, and that are specific to your software application (i.e. not generally useful in the runtime environment). This is the raw Linux version of your application without any specific SME Server integration code. For example, if your application is already available for Linux in the form of RPMs - these RPMs are what we are referring to. These are referred to as the application RPMs.
- Any new files that you have created specifically in order to integrate your application into the SME Server runtime environment - should be packaged into a single RPM, as explained in the next section. This is referred to as the integration RPM.
So, if your application is based on Linux software that has already been packaged into RPMs, then you will need to create one new RPM:the integration RPM.
If, on the other hand, your application is based on Linux software that has not yet been packaged into RPMs, then you will probably need to create at least two RPMs: one or more application RPMs, and the integration RPM.
Finally, for simple customizations (such as the loggerdemo example earlier in this manual) there may be no application RPM at all. This would be typical if the point of the application is to change the server configuration without really adding a new software package. In this case you need only the integration RPM which contains the new template fragments, user interface screens, etc..
All files on the system, except for user data, must be installed by RPMs.
Setting up your RPM development environment
If you haven't done so already, set up an RPM development environment. If you are using an SME Server as your development environment, you will need to alter your user account to enable regular login. If you want to enable account "joe", then you would type the following commands from the root account:
chsh -s /bin/bash joe db accounts setprop joe Shell /bin/bash
Then you should be able to log in to the server as user "joe", and get a Linux command line prompt. Log in, then type the following commands to set up your RPM work area:
cd ~/ mkdir -p rpms/{SRPMS,BUILD,SOURCES,SPECS,RPMS,lib} mkdir -p rpms/RPMS/{i386,noarch} echo "%_topdir $HOME/rpms" > ~/.rpmmacros
You will now find that you have a directory called rpms in which you will do your work. Under this are the following subdirectories:
- SOURCES
- The base material from which RPMs are built -- source code, tarballs, etc.
- BUILD
- Working area used by the rpmbuild program during RPM creation
- SPECS
- Specification files for building RPMs
- SRPMS
- Source RPMS (created by build process)
- RPMS
- Binary RPMS (created by build process). Has subdirectories noarch and i386 for architecture independent and x86 platforms respectively.
As you prepare software to turn into RPMs, you will place files in these directories as appropriate. The following sections will describe what goes where as each item is covered.
Tip: As you start work on an RPM for version x.y.z of a package, create a subdirectory rpms/SOURCES/yourpackage-x.y.z/ to work in.
mkdir rpms/SOURCES/yourpackage-x.y.z
Under this directory there should be a subdirectory called root, under which is an image of the file hierarchy that will be installed by the RPM.
mkdir rpms/SOURCES/yourpackage-x.y.z/root
Building an RPM
This section describes the process for building an RPM - step by step.
Choose a name and version number for your package. We are going to package the complete loggerdemo example and will use loggerdemo and 1.0.0 as the name and version number.
Collect all of the files which have been created in the previous sections into the /tmp/ directory. There is one additional file createlinks which looks like this:
#!/usr/bin/perl -w use esmith::Build::CreateLinks qw(:all); use File::Basename; my $panel = "manager"; panel_link("loggerdemo", $panel);
Create the directory hierarchy required for building the RPM. This is very close to the hierarchy on the installed system.
# Change to the SOURCES directory cd ~/rpms/SOURCES # Remove old files (check that you don't need anything here!) rm -rf loggerdemo-1.0.0 # Create new directory mkdir loggerdemo-1.0.0 cd loggerdemo-1.0.0 # The crontab template fragment mkdir -p root/etc/e-smith/templates/etc/crontab cp /tmp/25templatedemo root/etc/e-smith/templates/etc/crontab # The web panel description mkdir -p root/etc/e-smith/web/functions cp -p /tmp/loggerdemo !$ # The web panel implementation mkdir -p root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel cp -p /tmp/loggerdemo.pm !$ # The web panel English localisation mkdir -p root/etc/e-smith/locale/en-us/etc/e-smith/web/functions cp -p /tmp/loggerdemo-en !$ # The createlinks auxiliary file cp -p /tmp/createlinks . # The DB fragments should be created as files mkdir -p root/etc/e-smith/db/configuration/defaults/loggerdemo echo "service" > !$/type echo "enabled" > !$/status echo "10" > !$/Interval
Your directory structure should now look like this:
[gordonr@sevendev1 loggerdemo-1.0.0]$ find . -type f ./root/etc/e-smith/templates/etc/crontab/25templatedemo ./root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/loggerdemo ./root/etc/e-smith/web/functions/loggerdemo ./root/usr/lib/perl5/site_perl/esmith/FormMagick/Panel/loggerdemo.pm ./root/etc/e-smith/db/configuration/defaults/loggerdemo/{type|status|Interval} ./createlinks
Package the directory into a tarball: cd ~/rpms/SOURCES
tar zcvf loggerdemo-1.0.0.tar.gz loggerdemo-1.0.0
Create the RPM specification "SPEC" file ~/rpms/SPECS/loggerdemo.spec which looks like this:
%define name loggerdemo %define version 1.0.0 %define release 01 Summary: SME Server logger demo Name: %{name} Version: %{version} Release: %{release} License: GPL Group: Networking/Daemons Source: %{name}-%{version}.tar.gz Packager: Fred Frog <red@example.com> BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot BuildArchitectures: noarch %description Logger Demo sample application. %changelog * Thu Feb 2 2006 Fred Frog <fred@example.com> - 1.0.0-01 - Original version %prep %setup %build perl createlinks %install rm -rf $RPM_BUILD_ROOT (cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT) rm -f %{name}-%{version}-filelist /sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist %clean rm -rf $RPM_BUILD_ROOT %post /sbin/e-smith/expand-template /etc/crontab true %postun /sbin/e-smith/expand-template /etc/crontab true %files -f %{name}-%{version}-filelist %defattr(-,root,root)
Note the %post (post-installation) and %postun (post-uninstallation) statements which expand the /etc/crontab template after installing or uninstalling the RPM.
Check that your RPM will build OK with "build prepare":
cd ~/rpms/SPECS rpmbuild -bp loggerdemo.spec
The last line of output should be + exit 0 if rpmbuild is successful.
Run the rpmbuild command again to actually create your RPM with the "build all" options:
rpmbuild -ba loggerdemo.spec
If everything was successful, the last line of output should again be + exit 0.
The RPMs should have been generated and put into ~/rpms/RPMS/noarch/ as this program can run equally well on any platform. A source RPM should also exist in ~/rpms/SRPMS/.
Test your RPM by installing it on an SME Server test box.
sudo yum localinstall ~/rpms/RPMS/noarch/loggerdemo-1.0.0-01.noarch.rpm Preparing... ########################################### [100%] 1:loggerdemo ########################################### [100%] Migrating existing database mailpatterns Migrating existing database hosts Migrating existing database configuration Migrating existing database yum_repositories Migrating existing database networks Migrating existing database yum_updates Migrating existing database yum_installed Migrating existing database spamassassin Migrating existing database accounts Migrating existing database backups Migrating existing database yum_available Migrating existing database domains
The customization should be fully installed, and the /etc/crontab file should show the customization.
Then remove the customization:
sudo rpm -e loggerdemo
The customization should be completely gone, and the /etc/crontab file should look the way it did before.
The createlinks script
The source tarballs of an RPM should not include symbolic links as they are difficult to store under many version control systems and cause issues when generating patches. Since the SME Server uses many symbolic links, there are simple methods for creating the ones required. This is done through the createlinks script which is called from the %build section of the SPEC file. Let's examine one. It starts with the standard Perl script header and an import of the required module:
#!/usr/bin/perl -w use esmith::Build::CreateLinks qw(:all);
The templates2events function can be used to create the appropriate templates2expand links in various events:
my $imap = "/var/service/imap"; my $imaps = "/var/service/imaps"; templates2events("/etc/dovecot.conf", qw(bootstrap-console-save console-save)); templates2events("$imap/config", qw(bootstrap-console-save email-update)); templates2events("$imaps/config", qw(bootstrap-console-save email-update));
Note that the first argument is a filename and the second argument is a list of events in which to create the link. The safe_symlink function can be used to create a generic symbolic link, as well as the directory hierarchy enclosing that link:
for my $event (qw( email-update ldap-update network-create network-delete )) { safe_symlink("sigusr1", "root/etc/e-smith/events/$event/services2adjust/imap"); } safe_symlink("daemontools", "root/etc/rc.d/init.d/imap");
The event_link function is used to create the links from the event directories to the generic actions directory. For example:
for my $event (qw(post-upgrade)) { event_link("imap-relocate-maildirs", $event, "05"); }
creates a symbolic link S05imap-relocate-maildirs in the post-upgrade event. The target of the symbolic link will be the imap-relocate-maildirs script in the /etc/e-smith/events/actions/ directory.
Finally, the service_link_enhanced function makes it simple to create the /etc/rc.d/rc7.d and similar startup symlinks:
service_link_enhanced("imap", "S55", "7"); service_link_enhanced("imap", "K45", "6"); service_link_enhanced("imap", "K45", "0"); service_link_enhanced("imap", "K45", "1");
More documentation on this module can be seen with the command perldoc esmith::Build::CreateLinks.