Skip to content

Creating a RPM Package for a POCO Application

Günter Obiltschnig edited this page Jun 6, 2020 · 4 revisions

Here is a RPM spec file template (pocoServiceExample.spec) for creating a RPM package for a POCO-based server application. Requires the systemd pocoServiceExample.service file. Contributed by Jeff Adams.

To build the package with rpmbuild:

$ rpmbuild -bb --define 'PSEDIR /SOMEROOTDIR' pocoServiceExample.spec

pocoServiceExample.spec

Name: Poco Service Example
Version: 1.0.0.0
Release: 1
Summary: Best Darn Poco Service Ever
License: Proprietary Licensed Software (C) Copyright 2019-2020 INSERT COMPANY HERE. All rights reserved.
URL: https://SOMEURL
BuildRoot: ~/rpmbuild/

%description
Best Darn Poco Service Ever shows how to use a Poco Service in a *nix enviroment that is built with a modern gcc and uses systemd instead of System V init scripts

%prep

%build

%install
echo "BUILDROOT = $RPM_BUILD_ROOT"

ORIGINAL_DIR=$PWD

mkdir -p $RPM_BUILD_ROOT/opt/SOMEPRODUCT/bin/
mkdir -p $RPM_BUILD_ROOT/opt/SOMEPRODUCT/doc/
mkdir -p $RPM_BUILD_ROOT/opt/SOMEPRODUCT/etc/
mkdir -p $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib/
mkdir -p $RPM_BUILD_ROOT/etc/systemd/system/

cp %{PSEDIR}/build/THEBINARY $RPM_BUILD_ROOT/opt/SOMEPRODUCT/bin

cp %{PSEDIR}/EXTRADOC.pdf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/doc

# Poco logging setup
cp %{PSEDIR}/NewRelic/etc/THEBINARY.ini $RPM_BUILD_ROOT/opt/SOMEPRODUCT/etc 

# systemd configuration
cp %{PSEDIR}/NewRelic/scripts/pocoServiceExample.service $RPM_BUILD_ROOT/etc/systemd/system

# require Poco libs. Add more as needed.
cp /usr/local/lib/libPocoFoundation.so.71  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib
cp /usr/local/lib/libPocoUtil.so.71  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib
cp /usr/local/lib/libPocoXML.so.71  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib
cp /usr/local/lib/libPocoJSON.so.71  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib

# modern C++ runtime
cp ~/opt/gcc-9.1.0/lib64/libstdc++.so.6.0.26  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib
cp ~/opt/gcc-9.1.0/lib64/libgcc_s.so  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib
cp ~/opt/gcc-9.1.0/lib64/libgcc_s.so.1  $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib

cd $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib

# set the symbolic links
ln -s libPocoFoundation.so.71 libPocoFoundation.so
ln -s libPocoUtil.so.71 libPocoUtil.so
ln -s libPocoXML.so.71 libPocoXML.so
ln -s libPocoJSON.so.71 libPocoJSON.so
ln -s libstdc++.so.6.0.26 libstdc++.so
ln -s libstdc++.so.6.0.26 libstdc++.so.6

cd $ORIGINAL_DIR

# usual suspects
cp %{PSEDIR}/CONTACT $RPM_BUILD_ROOT/opt/SOMEPRODUCT
cp %{PSEDIR}/EULA.txt $RPM_BUILD_ROOT/opt/SOMEPRODUCT/LICENSE
cp %{PSEDIR}/VERSION $RPM_BUILD_ROOT/opt/SOMEPRODUCT
cp %{PSEDIR}/README $RPM_BUILD_ROOT/opt/SOMEPRODUCT

exit

%pre

# setup to run THEBINARY under a non-privileged user and group
if cat /etc/group | grep THEGROUP: >/dev/null 2>&1 || :
then 
  echo "Creating group THEGROUP"
  groupadd -r THEGROUP >/dev/null 2>&1 || :
else
  echo "Group THEGROUP already exists"
fi

if cat /etc/passwd | grep THEUSER: >/dev/null 2>&1 || :
then 
  echo "Creating user THEUSER"
  useradd -g THEGROUP -d /home/THEUSER -m -s /bin/bash \
    -c THEUSER Account" THEUSER >/dev/null 2>&1 || :
else
  echo "User THEUSER already exists"
fi

# setup to send log files to an appropriate location taking into account normal protections
echo "Creating log directory and setting permisssions on log directory"
if ! test -e "/var/log/SOMEPRODUCT"
then
   mkdir -p "/var/log/SOMEPRODUCT"  >/dev/null 2>&1 || :
fi

chown THEUSER:THEGROUP "/var/log/THEPRODUCT"  >/dev/null 2>&1 || :
chmod 0770 "/var/log/THEPRODUCT"  >/dev/null 2>&1 || :

# setup to send pid files to an appropriate location taking into account normal protections
echo "Creating pid directory and setting permisssions on pid directory"
if ! test -e "/var/run/THEPRODUCT"
then
   mkdir -p "/var/run/THEPRODUCT"  >/dev/null 2>&1 || :
fi

chown THEUSER:THEGROUP "/var/run/THEPRODUCT"  >/dev/null 2>&1 || :
chmod 0770 "/var/run/THEPRODUCT"  >/dev/null 2>&1 || :

%post

echo "Adding THEPRODUCT to system start/stop database."
systemctl enable pocoServiceExample.service >/dev/null 2>&1 || :

echo ""
echo "1) Execute systemctl start pocoServiceExample.service"
echo "2) Execute systemctl status pocoServiceExample.service"

%postun
echo "Removing THEPRODUCT from system start/stop database."
systemctl stop pocoServiceExample.service >/dev/null 2>&1 || :
systemctl disable pocoServiceExample.service >/dev/null 2>&1 || :

echo "Removing SOMEPRODUCT directory."
rm -rf /opt/SOMEPRODUCT >/dev/null 2>&1 || :

echo "Removing user and group."
userdel THEGROUP >/dev/null 2>&1 || :
rm -rf /home/THEUSER >/dev/null 2>&1 || :
groupdel THEGROUP >/dev/null 2>&1 || :

echo "Removing pid directory."
rm -rf /var/run/THEPRODUCT >/dev/null 2>&1 || :

echo "Not removing THEBINARY log files under /var/log/THEPRODUCT.  Remove both manually if desired."

%clean
rm -rf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/bin/
rm -rf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/doc/
rm -rf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/etc/
rm -rf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/lib/
rm -rf $RPM_BUILD_ROOT/opt/SOMEPRODUCT/
rm -rf $RPM_BUILD_ROOT/opt/
rm -rf $RPM_BUILD_ROOT/etc/systemd/system/
rm -rf $RPM_BUILD_ROOT/

%files
%attr(0755, THEUSER, THEGROUP) /opt/SOMEPRODUCT
%attr(0755, THEUSER, THEGROUP) /opt/SOMEPRODUCT/*
%attr(0750, THEUSER, THEGROUP) /opt/SOMEPRODUCT/bin/*
%attr(0444, THEUSER, THEGROUP) /opt/SOMEPRODUCT/doc/*
%attr(0660, THEUSER, THEGROUP) /opt/SOMEPRODUCT/etc/*
%attr(0660, THEUSER, THEGROUP) /opt/SOMEPRODUCT/lib/*
%attr(0750, root, root) /etc/systemd/system/pocoServiceExample.service

%changelog