We have created RPMs from .spec files that include installation of services for both upstart and systemd (hence, both .conf and .service) files. But the .conf and .service files contain hardwired paths to the service files.
myservice.service:
[Unit]
Description=My Service
[Service]
WorkingDirectory=/opt/myproduct
ExecStart=/opt/myproduct/myservice /opt/myproduct/myservicearg
Restart=always
[Install]
WantedBy=multi-user.target
myservice.conf:
description "My Service"
respawn
respawn limit 15 5
start on (stopped rc and runlevel [2345])
stop on runlevel [06]
chdir /opt/myproduct
exec /opt/myproduct/myservice /opt/myproduct/myservicearg
The installation paths are likely to change, but the brute force search-and-replace seems stone-age.
I have used Ansible with .j2 (Jinja2) template files, which seems like a nice way to use a variable for the binary/script paths. Using them might look something like this:
myservice.service.j2:
[Unit]
Description=My Service
[Service]
WorkingDirectory={{ myproductpath }}
ExecStart={{ myproductpath }}/myservice {{ myproductpath }}/myservicearg
Restart=always
[Install]
WantedBy=multi-user.target
myservice.conf.j2:
description "My Service"
respawn
respawn limit 15 5
start on (stopped rc and runlevel [2345])
stop on runlevel [06]
chdir {{ myproductpath }}
exec {{ myproductpath }}/myservice {{ myproductpath }}/myservicearg
But I was unable to find anything that suggested this is a common approach for building RPMs. Is there a recommended way in RPMs to template these .conf and .service files, either filled in during RPM build or during install?
No. Rpm does not have any such templating tool. Most developers prefer classical sed:
%build
....
sed -i 's/{{ myproductpath }}/\/real\/path/g' myservice.conf.j2
mv myservice.conf.j2 myservice.conf
Or you can BuildRequires: ansible
and let ansible expand it. But that is a quite heavy tool for this job.