Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get systemd variables to survive a reboot?

I have a product provided by a third party vendor. It includes many services for which they provide initd style startup scripts. There is one script for each service provided.

These scripts reference variables like JAVA_HOME, THE_PRODUCT_HOME and so on. The expectation from the vendor that I must edit these scripts manually and hard code the correct values. I would rather that these variables be initialised from environmental variables obtained from systemd when the system boots.

I know I can create an override configuration file for each of the services to provide the necessary envirables (a.k.a. environmental variables) using systemctl edit theService but:

  1. There are quite a few startup scripts
  2. The base variables are all the same
  3. I would like to avoid "systemctl edit"ing each of the supplied scripts if I can

So far I've tried using systemctl set-environment VAR_NAME=some_value.

This works perfectly - until I restart the system. It seems like the variables set this way are globally defined, but do not survive a reboot. I've also tried using systemctl daemon-reload just in case that is needed to "commit" the settings (but it doesn't seem to save the global envirables).

For now, I've edited each one of the supplied startup scripts and source /path/to/theGlobalVariablesINeed.sh

This works fine as a workaround but is not my preferred solution going forward...

Here is an illustration of what is happening:

define some variables

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@dav1-td1 -> ~] #

[root@dav1-td1 -> ~] # systemctl set-environment SYSD_PRODNAME_JAVA_HOME=/usr/java/jdk1.8.0_181-amd64/jre
[root@dav1-td1 -> ~] # systemctl set-environment SYSD_PRODNAME_HOME=/opt/TheProduct-1.2.3
[root@dav1-td1 -> ~] # systemctl daemon-reload        # This is optional, if I run the reload, or do not run the reload, the variables are still lost over a reboot.

demonstrate that the variables are set.

#### Now some variables are set, If I restart a service, the service will
#### Pick up these environmental variable settings.

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
SYSD_PRODNAME_HOME=/opt/TheProduct-1.2.3
SYSD_PRODNAME_JAVA_HOME=/usr/java/jdk1.8.0_181-amd64/jre
[root@dav1-td1 -> ~] #

System restart

#### After restart, the variables have disappeared !?!?

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@dav1-td1 -> ~] #

As mentioned above, when I restart the system, any envirables I set using systemctl set-environment VAR=value are lost.

I need these variables to survive a restart (without using per service override files and without having to source a file that contains all of the variables)

like image 729
GMc Avatar asked Jun 07 '19 02:06

GMc


People also ask

Where do I put Systemd environment files?

Systemd Files and Paths Unit files are stored in the /usr/lib/systemd directory and its subdirectories, while the /etc/systemd/ directory and its subdirectories contain symbolic links to the unit files necessary to the local configuration of the host. We recommend putting your scripts in /etc/systemd/system .

What is Environmentfile?

Description. The /etc/environment file contains variables specifying the basic environment for all processes. When a new process begins, the exec subroutine makes an array of strings available that have the form Name=Value. This array of strings is called the environment.

How to set environment variables to survive a restart?

I need these variables to survive a restart (without using per service override files and without having to source a file that contains all of the variables) There are different ways you can approach this problem. 1. Set the environment variable using the systemd config You can edit the /lib/systemd/system/system.conf and add the content like below

How to set the environment variable in systemd?

Set the environment variable using the systemd config You can edit the /lib/systemd/system/system.conf and add the content like below 2. Set the environment variable using another systemd service

Should systemd give priority to restart=on-abnormal over onfailure=systemd-reboot?

Restart=on-abnormal From the documentation ( systemd.service and systemd.service ), I'd expect that if I kill foo_app in a way such that Restart=on-abnormal is triggered (e.g. killall -9 foo_app ), systemd should give priority to Restart=on-abnormal over OnFailure=systemd-reboot.service and not start systemd-reboot.service.

When does a service restart in systemd enter the failed state?

A service unit using Restart= enters the failed state only after the start limits are reached. [snip] Note that service restart is subject to unit start rate limiting configured with StartLimitIntervalSec= and StartLimitBurst=, see systemd.unit (5) for details.


1 Answers

There are different ways you can approach this problem.

1. Set the environment variable using the systemd config

You can edit the /lib/systemd/system/system.conf and add the content like below

[Manager]
DefaultEnvironment=A=B C=D

2. Set the environment variable using another systemd service

[Unit]
Description=Example systemd service init

[Service]
Type=simple
ExecStart=/bin/systemctl set-environment VAR_NAME=some_value

[Install]
WantedBy=sysinit.target

The import point is using WantedBy=sysinit.target so this is loaded early

and now we can create a simple service to test this

[Unit]
Description=Example systemd service.

[Service]
Type=simple
ExecStart=/usr/bin/env

[Install]
WantedBy=multi-user.target

and the result

root@vagrant:/lib/systemd/system# systemctl status tarun
● tarun.service - Example systemd service.
   Loaded: loaded (/lib/systemd/system/tarun.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sat 2019-06-15 11:31:17 UTC; 5s ago
  Process: 1712 ExecStart=/usr/bin/env (code=exited, status=0/SUCCESS)
 Main PID: 1712 (code=exited, status=0/SUCCESS)

Jun 15 11:31:17 vagrant systemd[1]: Started Example systemd service..
Jun 15 11:31:17 vagrant env[1712]: A=B
Jun 15 11:31:17 vagrant env[1712]: C=D
Jun 15 11:31:17 vagrant env[1712]: LANG=en_US.UTF-8
Jun 15 11:31:17 vagrant env[1712]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Jun 15 11:31:17 vagrant env[1712]: VAR_NAME=some_value
like image 93
Tarun Lalwani Avatar answered Oct 28 '22 14:10

Tarun Lalwani