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

RFE: support specifier expansion for first word of ExecStart= directives #3061

Closed
spiette opened this issue Apr 18, 2016 · 10 comments
Closed
Labels
pid1 RFE 🎁 Request for Enhancement, i.e. a feature request

Comments

@spiette
Copy link

spiette commented Apr 18, 2016

How to reproduce:
In a unit file, get an ExecStart directive like this:

ExecStart=/opt/%i/bin/service --args

It doesn't work, as documented (systemd.service(5): "Note that the first argument of the command line (i.e. the program to execute) may not include specifiers.", but the error message is cryptic.
Because systemd doesn't honor unit template specifier, the only option is to use another binary to spawn the process. For example, one can start it with

ExecStart=/bin/sh -c "exec opt/%i/bin/service --args"

which is not a contribution to the Zero Shell Project (http://0pointer.de/blog/projects/the-new-configuration-files).

The expected behaviour would be to support the specifiers in the executable name.

@poettering
Copy link
Member

There's a technical reason for this: selinux linux in some cases requires us to know the binary to invoke before a unit instantiated for the first time, so that the right label can be derived for sockets. That's why we prohibit this in general. I am not sure we can really change that without compromising on the SELinux logic.

@poettering poettering added RFE 🎁 Request for Enhancement, i.e. a feature request pid1 labels Apr 18, 2016
@evverx
Copy link
Member

evverx commented Apr 18, 2016

Actually, the program to execute may include specifiers (that bug was fixed by bd1b973).
See #2646 (comment)

@DrYak
Copy link

DrYak commented May 23, 2016

Hello !

I'm on Debian 8 Jessie - and that one ships with a version that doesn't seem to expand specifiers in executable name.

In addition to the shell-trick mentioned by @spiette, there's another one that I use:

ExecStop=/lib64/ld-linux-x86-64.so.2 /usr/local/bin/%i-cli stop

I'm simply manually running the ELF-interpreter. (Basically the same idea as manually running /usr/bin/perl script.pl instead of trusting the she-bang of the script)

Any idea when/if there will be official support for specifiers expansion in systemd? At least for specifiers than can be statically determined in advance by systemd (like template, machine, etc.)

@poettering poettering changed the title RFE: support %i/%I specifiers for ExecStart directives in templates RFE: support specifier expansion for ExecStart= directives May 26, 2016
@rektide
Copy link

rektide commented Jul 18, 2016

Been working around lack of %h by calling /usr/bin/env everywhere, but doesn't feel great (having to set SyslogIdentifier= isn't fun). And it still presupposes that you've figured out how to setup PATH in your user session (systemctl --user import-environment PATH). It'd be really appreciated by user session folks if they had an effective way to share ~/ based scripts among themselves; currently requires manual intervention for each and every user (manually setting homedir in ExecStart, or env/PATH hackery), and that's slowing down user session adoption.

@poettering poettering changed the title RFE: support specifier expansion for ExecStart= directives RFE: support specifier expansion for first word of ExecStart= directives Oct 10, 2016
@james-lawrence
Copy link

@poettering would this issue be a good one for a new contributer to work on? I might be willing to put some time towards getting it implemented.

@keszybz
Copy link
Member

keszybz commented Oct 27, 2016

Yes, a patch for this would be welcome. The tough part would be figure out how this interacts with selinux, i.e. no selinux checks should be called with the unexpanded path.

@r14c
Copy link

r14c commented Nov 2, 2016

@pottering I don't see how permitting specifier expansion makes a difference, you have to resolve them before the command is useful in any case.

poettering added a commit to poettering/systemd that referenced this issue Dec 5, 2016
This monopolizes unit file specifier expansion in load-fragment.c, and removes
it from socket.c + service.c. This way expansion becomes an operation done exclusively at time of loading unit files.

Previously specifiers were resolved for all settings during loading of unit
files with the exception of ExecStart= and friends which were resolved in
socket.c and service.c. With this change the latter is also moved to the
loading of unit files.

Fixes: systemd#3061
oleeander added a commit to oleeander/systemd that referenced this issue Feb 9, 2018
Command lines now accept specifiers within the
first argument of command lines.

see issues systemd#3061, systemd#679 and pr systemd#4835
oleeander added a commit to oleeander/systemd that referenced this issue Feb 9, 2018
Command lines now accept specifiers within the first argument.

see issues systemd#3061, systemd#679 and pr systemd#4835
keszybz pushed a commit that referenced this issue Feb 9, 2018
#8146)

Command lines now accept specifiers within the first argument.

see issues #3061, #679 and pr #4835
@gnat
Copy link

gnat commented May 21, 2021

This is a big hangup for newcomers @poettering Think of it this way- most everyone who gets into writing .service files wastes hours on this conclusion in hopes of getting %h or some form of variable working in ExecStart= especially useful for --user userland systemd.

Collectively this must add up to 100,000+ hours of wasted time. Maybe there should be an effort to improve systemd ergonomics here and truly address the SELinux issue.

@keszybz
Copy link
Member

keszybz commented May 21, 2021

Oh man, aggressive commenting on a issue that was closed five years ago is also not a best way to improve anything. The way that ExecStart works is now quite a bit more flexible compared to the state 5 years ago.

@gnat
Copy link

gnat commented May 21, 2021

Correct me if I'm mistaken, but the main reason why this feature is important is because one cannot write portable userland .service files with ExecStart pointing to user binaries such as in /home/USER/.local/bin. This is essential for portable rootless services.

The way that ExecStart works is now quite a bit more flexible compared to the state 5 years ago.

If this was resolved somehow I'd like to know because I've just encountered this in 2021.

Should I be opening a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pid1 RFE 🎁 Request for Enhancement, i.e. a feature request
Development

No branches or pull requests

9 participants