Modify systemd unit file without altering upstream unit file
I have installed the pimd
service by means of apt
. This comes with an upstream systemd
unit file (/lib/systemd/system/pimd.service
).
I want the service to be restarted when for some reason it gets killed, hence I wish to add the line Restart = always
in the unit file.
However, I don’t want to modify the upstream unit file.
Is there any workaround for this?
Solution 1:
You have two options:
-
Copy the unit file from
/lib/systemd/system/
to/etc/systemd/system/
.
And then make your modifications in/etc/systemd/system/pimd.service
to completely override the unit file(s) supplied by the package maintainer.The command
systemctl edit --full <service-name>
automates this for you. -
You can alter or add specific configuration settings for a unit, without having to modify unit files by creating
.conf
files in a drop-in directory/etc/systemd/system/<unit-name>.<unit-type>.d/
i.e. create a/etc/systemd/system/pimd.service.d/restart.conf
The command
systemctl edit <service-name>
performs these steps for you.
See man systemd.unit
Solution 2:
The RHEL documentation recommends two ways:
- Extend the default unit file by creating a configuration directory and file under
/etc/systemd/system/[name-goes-here].service.d/config_name.conf
In this case the file would need to contain something like this:
[Service]
Restart=always
This is what systemctl edit [name-goes-here]
does, it creates that directory and override.conf
within it.
Create a copy of the original unit file
/usr/lib/systemd/system/
in/etc/systemd/system/
and make changes there.
I would try option one but they are both viable options. Either way remember to run systemctl daemon-reload
after making the changes.
RHEL documentation on Creating and Modifying systemd Unit Files
Solution 3:
Consider using a script to read the upstream configuration, modify it, and spit it out to drop-in file.
For example, I use Chef and here's a piece of ruby (library) that parses marathon systemd unit file to get original ExecStart from it
require 'inifile'
module Dcos
def get_execstart_from_unit_file
marathon_systemd_unit_file =
IniFile.load('/etc/systemd/system/dcos-marathon.service')
return marathon_systemd_unit_file['Service']['ExecStart']
end
end
Then in the recipe, I create the drop-in file to append an option to ExecStart
chef_gem 'inifile'
exec_start_orig = get_execstart_from_unit_file
systemd_service_drop_in 'dcos-marathon' do
override 'dcos-marathon.service'
precursor 'Service' => { 'ExecStart' => nil }
service do
exec_start exec_start_orig + ' --env_vars_prefix "DCOS_MARATHON_"'
end
end