Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

please consider having variables for an entire unit file #618

Closed
Zugschlus opened this issue Jul 18, 2015 · 17 comments
Closed

please consider having variables for an entire unit file #618

Zugschlus opened this issue Jul 18, 2015 · 17 comments

Comments

@Zugschlus
Copy link

Hi,

I'd like to be able to write:

Environment="CONFFILE=/etc/nifty.conf"
[Unit]                                                                          
Description=my nifty service
ConditionPathExists=$CONFFILE

[Service]
ExecStart=/usr/sbin/nifty -f $CONFFILE

This does not work at the moment since the Environment directive is part of the Service definition.
Writing the file name explicitly in the unit is possible, but error prone, and there may be situations where the file name is referenced multiple times.

Please consider adding a variable mechanism to make systemd unit files more robust.

Greetings
Marc

@johannbg
Copy link
Contributor

This one should be closed as wont-fix and fixed upstream nifty.

The relevant daemon should a) be able to check it's own configuration file and b) fail if it's own configuration file is missing and c) we should not support writing hackis unit files with broken and obsoleted use of environment definitions like this.

@Zugschlus
Copy link
Author

Ugly unit files working around this shortcoming are already written today. It would be really really nice to fix this in one place, systemd, other than in all daemons around in the world.

Additionally, having the daemon exit on a missing conffile might cause error messages in logs, which may trip off more or less sophisticated log checking mechanisms like SIEM solutions.

Additionally, please note that "nifty" is not a daemon existing in real life, just a replacement for any daemon as this idiom will be all over the place.

@mrvn
Copy link

mrvn commented Jul 21, 2015

and who says the variable is the config file. Could be anything that is referenced multiple times.

@johannbg
Copy link
Contributor

Irrelevant.

Environmental entries unit files are more or less obsoleted
( unless those are environmental entries required to be present for the daemon startup itself )

It makes absolutely no sense to do something like this in unit files.

Environment="CONFFILE=/etc/nifty.conf"

[Unit]
Description=my nifty service
ConditionPathExists=$CONFFILE
( or )
Environment="CONFFILE=/etc/nifty.conf"

[Service]

( or )
Environment="CONFFILE=/etc/nifty.conf"
ExecStart=/usr/sbin/nifty -f $CONFFILE

As opposed to this...

[Unit]
Description=my nifty service
ConditionPathExists=/etc/nifty.conf

[Service]
ExecStart=/usr/sbin/nifty -f /etc/nifty.conf

The amount for the administrator to edit or overwrite unit files with environmental entry's is exactly the same as if the path would be absolute.

Unit files aren't shell scripts nor do they usually grow far beyond 12 lines for well written daemon and services.

@johannbg
Copy link
Contributor

Another common mistake done by people is to use a environmental file which contains something like this and think it's useful or beneficial in some manner when all it does is making the administrators life more difficult since he has to have a look at two places encase he wants to change the daemon/service startup setting...

/path/to/my-daemon-environment-file
OPTIONS="foo"

and refer to it like so

[Unit]
Description=Sample daemon

[Service]
EnvironmentFile=/path/to/my-daemon-environment-file
ExecStart=/usr/bin/my-daemon "$OPTIONS"

[Install]
WantedBy=multi-user.target

@Zugschlus
Copy link
Author

Having to look in /lib/systemd, /etc/systemd and /etc/systemd/system/foo.d is so much easier, yeah . right.

@zonque
Copy link
Member

zonque commented Jul 21, 2015

@Zugschlus well, you would still have to look at those too, right? All @johannbg is saying that fiddling with env vars just adds to the complexity.

@johannbg
Copy link
Contributor

@zonque right adds to the complexity but the complexity @Zugschlus is referring to should not exist after the introduction of systemctl edit .

If it still does we need to fix it's implementation based on my comments ( which was based on collected administrators feedback ) in the relevant bug I filed in bz.rh regarding that and or put more emphasize on administrators to use the tool they have been provide with, to create and or edit unit(s)

@poettering
Copy link
Member

I am very sure we should not add a concept like that. Unit files are supposed to be simple, and easily parseable by 3rd party software software. They hence should not contain a macro language.

We only support env var expansion in ExecStart= and friends, and we resolve the env vars at execution time (not at conf parsing time), and that's intended.

Generally: unit files are configuration files. By providing tools like "systemctl edit", "systemctl cat" and "systemd-delta" we make it easy to alter them, extend them, and check for differences from the vendor defaults. They should be simple enough to grok them for 3rd party scripts and programs as well as admins without understanding for macro languages.

Use of EnvironmentFile= is pretty much always a bad idea, and we probably should never have added that, since it invites packagers to reintroduce the /etc/default/ and /etc/sysconfig/ madness we try to remove.

Sorry, but I am very strongly against in adding this. We don't want to be shell. If you need shell, then use shell and execute your script from ExecStart=, but don't expect us to turn systemd into another shell, since there are already good ones out there.

Sorry!

@poettering
Copy link
Member

(I don't think that daemons should fail without config file btw. I think a daemon should be robust, and work without any /etc at all, and just fall back to sane defaults when no configuration file exists.)

@poettering
Copy link
Member

Having to look in /lib/systemd, /etc/systemd and /etc/systemd/system/foo.d is so much easier, yeah . right.

Note that systemd will help you with that. "systemctl status" shows you all unit files and their drop-ins that are used for a unit. Also "systemctl edit" will help you overriding or altering unit files, and "systemctl cat" will show you the contents of the unit files currently in place.

@Zugschlus
Copy link
Author

Fine. I'll note that as "systemd upstream wants the unit file to be this ugly" with a reference here in my code. I can live with that.

@gmkarl
Copy link

gmkarl commented Mar 6, 2016

Just to note my usecase, I'm creating services which update user-configurable paths when they change.

I am currently writing an extra two systemd services to work around the design choice mentioned in this bug report -- the extra services watch /etc/[conffile] and update /etc/systemd/system/[daemon].path.d/*.conf when it changes.

I'm curious what a better solution would be. I could put the inotify logic in the services themselves, but that seems like even more increased complexity than the conffile watcher service. Things would be simpler, more maintainable, and have fewer possible components to fail, if EnvironmentFile could be evaluated when parsed, and apply to the whole unit file.

@protoism
Copy link

HI all,
sorry for resurrecting this thread.

I'm just writing a systemd service, and there are a couple of environment variables which in my opinion are system configuration. Nothing to do with the service.

Just an example:
LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libtcmalloc.so"
LIBVA_DRIVERS_PATH="/usr/lib/x86_64-linux-gnu/dri"
LIBVA_DRIVER_NAME="iHD"

Well I don't want to put them in the service, which is RPM / DEB distributed, because the ops should not touch the service file.

We typically deploy an empty configuration file in the broken-by-design sysconfig directory, and let the dirty job be done with ansible or dear old keyboard.

What are we supposed to do in this case?

Thanks a lot, keep up the good job!

@boucman
Copy link
Contributor

boucman commented Nov 23, 2019

This is not a support forum, but a bug tracker. Please ask those questions on the mailing list

That being said, the common pattern is to put those env variables in a file somewhere in /etc and have EnvironmentFile= in [Service] to load them. Your admin can then edit the file

Also note that an admin is meant to tweak service files. he does that by adding files in /etc/systemd/system, unit files will override the version in /usr/lib and drop-ins will append to the original file

As long as you put your services in /usr/lib, it's considered fine for the admin to tweak them that way.

@protoism
Copy link

Thanks boucman for the quick and kind reply, which makes a lot of sense.
I missed the /etc/systemd/system trick and I thought that... ehm... you were a little bit too draconian in "deprecating" environment files.
I was in need of support, without even knowing it.

@sjvudp
Copy link

sjvudp commented Jun 27, 2024

I wonder (leaving "environment" variables aside): Should there be a mechanism to define some kind of variables and use their value in a unit file? I think it would make sense. See also https://superuser.com/q/1847266/964771.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

9 participants