Discussion:
Best way of configuring service
(too old to reply)
Dan Tihelka
2012-09-23 21:04:39 UTC
Permalink
Dear all,
I porting the start scripts of cruisecontrol system to the native systemd
service configuration. It goes quiet well, the only "trouble" I have with the
options configuration.

Since cruisecontrol is written in Java, there are two ways of how to configure
the daemon (and CC use them both): -D java properties and "classic" command
line options passed to the main jar.

I want to have the whole service highly configurable, So I have decided to
define Environment= item for each particular option. The result looks like:

Environment=cc.prop.item1="-Dcc.XXX=value1"
Environment=cc.prop.item2="-Dcc.XXX=value1"
Environment=cc.prop.item3="-Dcc.XXX=value1"
Environment=cc.prop.item4=
Environment=cc.prop.item5=

Environment=cc.opt.item1=-opt1 val1
Environment=cc.opt.item2=-opt2 val2
Environment=cc.opt.item3=-opt3 val3
Environment=cc.opt.item4=
Environment=cc.opt.item4=

Environment=cc.install.dir=/usr/shared/cruisecontrol

Where those undefined are left for user to be able to override the
configuration, since they MUST appear in the ExecStart= item which looks like:

ExecStart=/usr/bin/java -Dcc.install.dir=-Dcc.install.dir${cc.install.dir} -cp
${cc.install.dir}/dist $cc.prop.item1 $cc.prop.item2 ... $cc.prop.item5
-jar cruisecontrol-launcher.jar $cc.opt.item1
$cc.opt.item2 ... $cc.opt.item5


In this way, the user should be able to customize everything in
/etc/systemd/system/ configuration, simply re-defining the appropriate
Environment definitions.

However, there are two issues Iike to clarify:

1)
As you could see, one variable is used in two cases - particularly it is:

-Dcc.install.dir=-Dcc.install.dir${cc.install.dir} -cp ${cc.install.dir}/dist

I have observed that the env must be used in form ${XXX} when it is the part
of larger string (despite the form ${XXX} having its "special" meaning).

So the question is: do I it right? Is the concept I have chosen correct?


2)
The second issue is that (if I understand it right) everything I define by
Environment= will appear in ENV variables of the process started. Is is true?

What If I don't want to export those variables to the service? I would guess
that it is the reason why -D properties are used instead of "raw" ENV
variables (which could simply be used as well)

Also, I have found the inability to resolve env definitions in other env
definitions being quiet limiting (although I suppose that some others are
complaining as well :-)) ).


So, I would like to ask you for your advice - what is the best way of handling
those two issues? What do you recommend to daemon upstream developers?

It seems to me that the purpose of ENV variables is slightly bit different from
using as constant definitions for ExecStart= command simplification (even shell
does not export them unless explicitly told, doesn't it). Although I may be
completely wrong.


Thank you and I wish you many happy system admins (anyway, I see systemd as
the best init system with the highest potential).

Best regards,
Dan
Lennart Poettering
2012-09-24 10:20:30 UTC
Permalink
Post by Dan Tihelka
Dear all,
I porting the start scripts of cruisecontrol system to the native systemd
service configuration. It goes quiet well, the only "trouble" I have with the
options configuration.
Since cruisecontrol is written in Java, there are two ways of how to configure
the daemon (and CC use them both): -D java properties and "classic" command
line options passed to the main jar.
I want to have the whole service highly configurable, So I have decided to
Environment=cc.prop.item1="-Dcc.XXX=value1"
Environment=cc.prop.item2="-Dcc.XXX=value1"
Environment=cc.prop.item3="-Dcc.XXX=value1"
Environment=cc.prop.item4=
Environment=cc.prop.item5=
Environment=cc.opt.item1=-opt1 val1
Environment=cc.opt.item2=-opt2 val2
Environment=cc.opt.item3=-opt3 val3
Environment=cc.opt.item4=
Environment=cc.opt.item4=
Environment=cc.install.dir=/usr/shared/cruisecontrol
Hmm, so systemd unit files are not really supposed to the place where
daemon-specific configuration bits are encoded. If a daemon requires
specific configuration my recommendation is always to introduce a proper
configuaration file for it, and not to encode this via env vars or in
the cmdline. Administrators will thank you for it!
Post by Dan Tihelka
I have observed that the env must be used in form ${XXX} when it is the part
of larger string (despite the form ${XXX} having its "special"
meaning).
Yes, please see the documentation for this in the section about
ExecStart= in systemd.service(5)
Post by Dan Tihelka
2)
The second issue is that (if I understand it right) everything I define by
Environment= will appear in ENV variables of the process started. Is is true?
Yes, as the name suggests env vars specified in "Evironment=" actually
do change the environment.
Post by Dan Tihelka
What If I don't want to export those variables to the service? I would guess
that it is the reason why -D properties are used instead of "raw" ENV
variables (which could simply be used as well)
systemd unit files are not supposed to be a macro engine, or a
programming language. My recommendation would be to fix the daemon to
read a normal configuration file natively and if that's ot possible just
wrap it in a normal shell script, rather then tryig to hammer unit files
into what you need here.

I mean, I do understand your needs, but we deliberately try to keep unit
files simple and devoid of any programming language antics. Because we
already have a pretty good one for these kinds of thigs, if that's what
you need, and that's shell.

I hope this is understandable,

Lennart
--
Lennart Poettering - Red Hat, Inc.
Daniel Tihelka
2012-09-24 19:58:17 UTC
Permalink
Post by Lennart Poettering
Post by Dan Tihelka
Dear all,
I porting the start scripts of cruisecontrol system to the native systemd
service configuration. It goes quiet well, the only "trouble" I have with the
options configuration.
Since cruisecontrol is written in Java, there are two ways of how to configure
the daemon (and CC use them both): -D java properties and "classic" command
line options passed to the main jar.
I want to have the whole service highly configurable, So I have decided to
Environment=cc.prop.item1="-Dcc.XXX=value1"
Environment=cc.prop.item2="-Dcc.XXX=value1"
Environment=cc.prop.item3="-Dcc.XXX=value1"
Environment=cc.prop.item4=
Environment=cc.prop.item5=
Environment=cc.opt.item1=-opt1 val1
Environment=cc.opt.item2=-opt2 val2
Environment=cc.opt.item3=-opt3 val3
Environment=cc.opt.item4=
Environment=cc.opt.item4=
Environment=cc.install.dir=/usr/shared/cruisecontrol
Hmm, so systemd unit files are not really supposed to the place where
daemon-specific configuration bits are encoded. If a daemon requires
specific configuration my recommendation is always to introduce a proper
configuaration file for it, and not to encode this via env vars or in
the cmdline. Administrators will thank you for it!
OK, thanks. I will try to change cruisecontrol in this way.

But still, there are java-specific options which must be set (and may
be required to be customized) as well - for example the -Xmx or -Xms
settings. And I am most likely not able to change it in java :-)

So, how to handle those? Yes, it can (rather simply) be done through
shell wrapper, but my intention was to try to avoid it (well, it was
motivated by the aim of systemd anyway - to get rid off shell scripts
from boot sequence). On the other hand, I understand that you don't
want to create a mega-features-everything-capable-shell-replacement
...

Anyway, one more ask - I have filled feature request at
https://bugs.freedesktop.org/show_bug.cgi?id=55163

Do you think that it is doable or completely useless? Where to look in
systemd code to implement this?

Thank you,
Dan
Post by Lennart Poettering
Post by Dan Tihelka
What If I don't want to export those variables to the service? I would guess
that it is the reason why -D properties are used instead of "raw" ENV
variables (which could simply be used as well)
systemd unit files are not supposed to be a macro engine, or a
programming language. My recommendation would be to fix the daemon to
read a normal configuration file natively and if that's ot possible just
wrap it in a normal shell script, rather then tryig to hammer unit files
into what you need here.
--
Lennart Poettering - Red Hat, Inc.
David Strauss
2012-09-24 20:26:27 UTC
Permalink
The EnvironmentFile= option may be useful for specifying a sort of
poor man's configuration file.
--
David Strauss
| ***@davidstrauss.net
Lennart Poettering
2012-09-24 20:36:34 UTC
Permalink
Post by Daniel Tihelka
But still, there are java-specific options which must be set (and may
be required to be customized) as well - for example the -Xmx or -Xms
settings. And I am most likely not able to change it in java :-)
If it is likely that you can find good defaults then I'd simply pass
them on the command line as is. Admins can then simply copy your
.service file from /usr to /etc and edit the command line there.
Post by Daniel Tihelka
Anyway, one more ask - I have filled feature request at
https://bugs.freedesktop.org/show_bug.cgi?id=55163
Do you think that it is doable or completely useless? Where to look in
systemd code to implement this?
Hmm, so this is harder actually than it might sounds, since we must
avoid NSS lookups from PID1. But I guess we could do this as part of the
minimal env var replacement we do for the command line too, in
execute.c (which rns in the forked off process, before we invoke the
service binary). That way you could write something like
"WorkingDirectory=$HOME" or so. I added this to the todo list now.

Lennart
--
Lennart Poettering - Red Hat, Inc.
Malte Starostik
2012-09-24 21:52:54 UTC
Permalink
Hi Dan,
Post by Daniel Tihelka
Post by Lennart Poettering
Hmm, so systemd unit files are not really supposed to the place where
daemon-specific configuration bits are encoded. If a daemon requires
specific configuration my recommendation is always to introduce a proper
configuaration file for it, and not to encode this via env vars or in
the cmdline. Administrators will thank you for it!
OK, thanks. I will try to change cruisecontrol in this way.
But still, there are java-specific options which must be set (and may
be required to be customized) as well - for example the -Xmx or -Xms
settings. And I am most likely not able to change it in java :-)
So, how to handle those? Yes, it can (rather simply) be done through
shell wrapper, but my intention was to try to avoid it (well, it was
motivated by the aim of systemd anyway - to get rid off shell scripts
from boot sequence). On the other hand, I understand that you don't
want to create a mega-features-everything-capable-shell-replacement
...
True, true...but a shell script doesn't *have* to be as ugly as what comes
with some widely used java frameworks and contain like 2k LOC of the most
abominable shell code history has seen just to collect what ends up in a bunch
of env vars and options to the java binary - of which the location is first
determined via large parts of this wrapper...

Actually I think it's a bug in the JRE if things can only be configured on the
command line and not via a (possibly JAR-specific) config file...
anyway, this seems like be one of the few cases where EnvironmentFile= might
be the best solution. As opposed to Environment= this makes it very easy for
the user to override some settings.
You could e.g. run java ... $JAVA_OPTS together with EnvironmentFile=-... (not
teh minus) so the file doesn't even have to exist, but iff the user wants/needs
to tweak memory options, it's only a matter of adding e.g. JAVA_OPTS="-Xms...
-Xmx..." to the env file. With Environment=... you require the user to
overwrite the whole unit instead.

HTH,
Malte
Colin Guthrie
2012-09-24 22:28:47 UTC
Permalink
Post by Malte Starostik
Hi Dan,
Post by Daniel Tihelka
Post by Lennart Poettering
Hmm, so systemd unit files are not really supposed to the place where
daemon-specific configuration bits are encoded. If a daemon requires
specific configuration my recommendation is always to introduce a proper
configuaration file for it, and not to encode this via env vars or in
the cmdline. Administrators will thank you for it!
OK, thanks. I will try to change cruisecontrol in this way.
But still, there are java-specific options which must be set (and may
be required to be customized) as well - for example the -Xmx or -Xms
settings. And I am most likely not able to change it in java :-)
So, how to handle those? Yes, it can (rather simply) be done through
shell wrapper, but my intention was to try to avoid it (well, it was
motivated by the aim of systemd anyway - to get rid off shell scripts
from boot sequence). On the other hand, I understand that you don't
want to create a mega-features-everything-capable-shell-replacement
...
True, true...but a shell script doesn't *have* to be as ugly as what comes
with some widely used java frameworks and contain like 2k LOC of the most
abominable shell code history has seen just to collect what ends up in a bunch
of env vars and options to the java binary - of which the location is first
determined via large parts of this wrapper...
Actually I think it's a bug in the JRE if things can only be configured on the
command line and not via a (possibly JAR-specific) config file...
anyway, this seems like be one of the few cases where EnvironmentFile= might
be the best solution. As opposed to Environment= this makes it very easy for
the user to override some settings.
You could e.g. run java ... $JAVA_OPTS together with EnvironmentFile=-... (not
teh minus) so the file doesn't even have to exist, but iff the user wants/needs
to tweak memory options, it's only a matter of adding e.g. JAVA_OPTS="-Xms...
-Xmx..." to the env file. With Environment=... you require the user to
overwrite the whole unit instead.
Well, you can use Environment= and EnvironmentFile=- in combination
here. Set the default JAVA_OPTS with Environment= (assuming the values
really are specific to this service) and then allow the user to
optionally override them via the EnvironmentFile all without having to
copy/edit the unit itself.

I'm not really a java guru, but is it common that some JAVA_OPTS might
be valid for multiple, different services? If so, then it would be worth
defining a "central" (i.e. not service specific) EnvironmentFile that is
sourced for all java services (e.g. /etc/sysconfig/java) but still allow
a service specific env file to override it (e.g.
/etc/sysconfig/myservice). In this case you'd just specificy two
EnvironmentFile=- lines in the unit. This might or might not make sense
as I said, so feel free to come to your own conclusions here.

Col
--
Colin Guthrie
gmane(at)colin.guthr.ie
http://colin.guthr.ie/

Day Job:
Tribalogic Limited http://www.tribalogic.net/
Open Source:
Mageia Contributor http://www.mageia.org/
PulseAudio Hacker http://www.pulseaudio.org/
Trac Hacker http://trac.edgewall.org/
Continue reading on narkive:
Loading...