I get build errors when using mvn unleash:perform because it tries to use the default Java VM to build the release instead of the one pointed to with JAVA_HOME or the one which was used to start the maven-unleash-plugin.
With -Dunleash.releaseArgs="--debug=true" -X, I can see that the outer Maven uses Java 11 and the inner uses 8.
I tried to fix this with:
mvn unleash:perform -Dunleash.releaseEnvironment="JAVA_HOME=$JAVA_HOME" -X |& tee mvn.log
but that leads to an NPE:
Caused by: java.lang.NullPointerException
at com.itemis.maven.plugins.unleash.steps.actions.BuildProject.setupInvocationRequest (BuildProject.java:123)
at com.itemis.maven.plugins.unleash.steps.actions.BuildProject.execute (BuildProject.java:73)
Is changing the default VM in Windows my only option?
In my case, the culprit was in .mavenrc (Linux) or %USERPROFILE%\mavenrc_pre.cmd (Windows, also check %USERPROFILE%\mavenrc_pre.bat). There, JAVA_HOME was hardcoded to some specific path.
The fix is to a) only set JAVA_HOME when it has no value and b) to display a warning (with path) when the variable is set. That way, people can't get confused by some silent behavior.
Solution in .mavenrc:
if [[ -z "$JAVA_HOME" ]]; then
export JAVA_HOME=...
echo "~/.mavenrc: Setting JAVA_HOME to $JAVA_HOME"
fi
For %USERPROFILE%\mavenrc_pre.cmd, use:
if "%JAVA_HOME%"=="" (
set JAVA_HOME=...
echo %USERPROFILE%\mavenrc_pre.cmd: Setting JAVA_HOME to %JAVA_HOME%
)
When I am trying to set environment variables using PowerShell in Windows Terminal with the command set test1=value1, I get no errors. However, when I try to check all environment variables using the set command, I get the following prompt:
cmdlet Set-Variable at command pipeline position 1
Supply values for the following parameters:
Name[0]:
I read that when using PowerShell you set environment vars using this:
$Env:test1 = "value1";
I want to set the variables so that on my backend in custom-environment-variables.json
I can store a name by which config can extract it using config.get("test").
custom-environment-variables.json:
{
"test": "test1",
}
But every time I try this, it says Error: Configuration property "test" is not defined.
Doing the same procedure CMD (either directly or through Windows Terminal) I get no issues whatsoever. Any ideas what might be causing this?
First, the easy part:
I get no errors but when I try to check all env. variables calling "set" I get the following prompt:
That's because the set command in PowerShell behaves differently. It's an alias for the PowerShell Set-Variable cmdlet. You can see this with Get-Alias.
Also, PowerShell variables are not environment variables. As you commented, the proper way to set an environment variable in PowerShell is with:
$env:variablename = "value"
The equivalent command to set (to get a list of all environment variables and their values) in PowerShell is:
Get-ChildItem env:
# Or using the alias
dir env:
# Or using another alias
ls env:
This access the PowerShell "environment provider", which is essentially (my grossly oversimplified summary) a "virtual drive/filesystem" that PowerShell provides which contains the environment variables. You can also create variables in here.
More reading: about_Environment_Variables from the PowerShell Doc.
As for the core issue with the config module, I haven't been able to reproduce that. It works correctly for me in both PowerShell and CMD. So let me run through my results in the hopes that it will help you see what might be different. All tests were performed in Windows Terminal, although as we've determined in the comments, this is more a difference in PowerShell vs. CMD for you:
config\default.json:
{
"test": "Original Value"
}
config\custom-environment-variables.json:
{
"test": "test1"
}
CMD without test1 variable set:
Running node in CMD:
> const config = require('config')
undefined
> config.get('test')
'Original Value'
>
CMD with test1 variable set:
Exit Node, and back in CMD:
>set test1=Override
>node
In Node:
Welcome to Node.js v14.16.1.
Type ".help" for more information.
> const config = require('config')
undefined
> config.get('test')
'Override'
>
PowerShell without test1 variable set:
Welcome to Node.js v14.16.1.
Type ".help" for more information.
> const config = require('config')
undefined
> config.get('test')
'Original Value'
>
PowerShell with test1 variable set:
In PowerShell:
PS1> $env:test1="Override"
PS1> node
In Node:
Welcome to Node.js v14.16.1.
Type ".help" for more information.
> const config = require('config')
undefined
> config.get('test')
'Override'
>
When I use any command with sudo the environment variables are not there. For example after setting HTTP_PROXY the command wget works fine without sudo. However if I type sudo wget it says it can't bypass the proxy setting.
First you need to export HTTP_PROXY. Second, you need to read man sudo, and look at the -E flag. This works:
$ export HTTP_PROXY=foof
$ sudo -E bash -c 'echo $HTTP_PROXY'
Here is the quote from the man page:
-E, --preserve-env
Indicates to the security policy that the user wishes to preserve their
existing environment variables. The security policy may return an error
if the user does not have permission to preserve the environment.
The trick is to add environment variables to sudoers file via sudo visudo command and add these lines:
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
taken from ArchLinux wiki.
For Ubuntu 14, you need to specify in separate lines as it returns the errors for multi-variable lines:
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
For individual variables you want to make available on a one off basis you can make it part of the command.
sudo http_proxy=$http_proxy wget "http://stackoverflow.com"
You can also combine the two env_keep statements in Ahmed Aswani's answer into a single statement like this:
Defaults env_keep += "http_proxy https_proxy"
You should also consider specifying env_keep for only a single command like this:
Defaults!/bin/[your_command] env_keep += "http_proxy https_proxy"
A simple wrapper function (or in-line for loop)
I came up with a unique solution because:
sudo -E "$#" was leaking variables that was causing problems for my command
sudo VAR1="$VAR1" ... VAR42="$VAR42" "$#" was long and ugly in my case
demo.sh
#!/bin/bash
function sudo_exports(){
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) "$#"
}
# create a test script to call as sudo
echo 'echo Forty-Two is $VAR42' > sudo_test.sh
chmod +x sudo_test.sh
export VAR42="The Answer to the Ultimate Question of Life, The Universe, and Everything."
export _EXPORTS="_EXPORTS VAR1 VAR2 VAR3 VAR4 VAR5 VAR6 VAR7 VAR8 VAR9 VAR10 VAR11 VAR12 VAR13 VAR14 VAR15 VAR16 VAR17 VAR18 VAR19 VAR20 VAR21 VAR22 VAR23 VAR24 VAR25 VAR26 VAR27 VAR28 VAR29 VAR30 VAR31 VAR32 VAR33 VAR34 VAR35 VAR36 VAR37 VAR38 VAR39 VAR40 VAR41 VAR42"
# clean function style
sudo_exports ./sudo_test.sh
# or just use the content of the function
eval sudo $(for x in $_EXPORTS; do printf '%q=%q ' "$x" "${!x}"; done;) ./sudo_test.sh
Result
$ ./demo.sh
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
Forty-Two is The Answer to the Ultimate Question of Life, The Universe, and Everything.
How?
This is made possible by a feature of the bash builtin printf. The %q produces a shell quoted string. Unlike the parameter expansion in bash 4.4, this works in bash versions < 4.0
Add code snippets to /etc/sudoers.d
Don't know if this is available in all distros, but in Debian-based distros, there is a line at or near the tail of the /etc/sudoers file that includes the folder /etc/sudoers.d. Herein, one may add code "snippets" that modify sudo's configuration. Specifically, they allow control over all environment variables used in sudo.
As with /etc/sudoers, these "code snippets" should be edited using visudo. You can start by reading the README file, which is also a handy place for keeping any notes you care to make:
$ sudo visudo -f /etc/sudoers.d/README
# files for your snippets may be created/edited like so:
$ sudo visudo -f /etc/sudoers.d/20_mysnippets
Read the "Command Environment" section of 'man 5 sudoers'
Perhaps the most informative documentation on environment configuration in sudo is found in the Command environment section of man 5 sudoers. Here, we learn that a sudoers environment variables that are blocked by default may be "whitelisted" using the env_check or env_keep options; e.g.
Defaults env_keep += "http_proxy HTTP_PROXY"
Defaults env_keep += "https_proxy HTTPS_PROXY"
Defaults env_keep += "ftp_proxy FTP_PROXY"
And so, in the OP's case, we may "pass" the sudoer's environment variables as follows:
$ sudo visudo -f /etc/sudoers.d/10_myenvwlist
# opens the default editor for entry of the following lines:
Defaults env_keep += "http_proxy HTTP_PROXY"
Defaults env_keep += "https_proxy HTTPS_PROXY"
# and any others deemed useful/necessary
# Save the file, close the editor, and you are done!
Get your bearings from '# sudo -V'
The OP presumably discovered the missing environment variable in sudo by trial-and-error. However, it is possible to be proactive: A listing of all environment variables, and their allowed or denied status is available (and unique to each host) from the root prompt as follows:
# sudo -V
...
Environment variables to check for safety:
...
Environment variables to remove:
...
Environment variables to preserve:
...
Note that once an environment variable is "whitelisted" as above, it will appear in subsequent listings of sudo -V under the "preserve" listing.
If you have the need to keep the environment variables in a script you can put your command in a here document like this. Especially if you have lots of variables to set things look tidy this way.
# prepare a script e.g. for running maven
runmaven=/tmp/runmaven$$
# create the script with a here document
cat << EOF > $runmaven
#!/bin/bash
# run the maven clean with environment variables set
export ANT_HOME=/usr/share/ant
export MAKEFLAGS=-j4
mvn clean install
EOF
# make the script executable
chmod +x $runmaven
# run it
sudo $runmaven
# remove it or comment out to keep
rm $runmaven
I'm starting a python script with supervisord on a linux debian platform. The user selected for executing the script shall depend on the value of an environmental variable. How can i make the field "user=" in a supervisord configuration file conditional?
First, I have added to the supervisor.service an environmental variable SPECIALUSER=myuser (file /lib/systemd/system/supervisor.service)
[Service]
ExecStart=/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl -c /etc/supervisor/supervisord.conf $OPTIONS reload
KillMode=process
Restart=on-failure
Environment=SPECIALUSER=myuser
Then I try to use the variable inside my supervisord.conf file:
[program:myprogram]
command=python myscript.py
user="if [ %(ENV_SPECIALUSER)s = myuser]; then root; else standarduser; fi"
But I get the following error when i try to reread the supervisord.conf
ERROR: CANT_REREAD: Invalid user name "if [ myuser = myuser ]; then root; else standarduser; fi" in section 'program:myprogram' (file: '/etc/supervisor/conf.d/supervisord.conf')
The environmental variable is interpreted correctly but the bash script, not.
I thought about entering the name of the user directly in the variable Environment=SPECIALUSER=root, but the environmental varialble is not always available.
If the environment variable is set to SPECIALUSER=myuser, I expect supervisor.d to interpret my program as
[program:myprogram]
command=python myscript.py
user=root
In all other cases as
[program:myprogram]
command=python myscript.py
user=standarduser
According to the documentation the user parameter value is never "interpreted" or sent to a shell. This means that it tries to use the entire value as the username.
http://supervisord.org/configuration.html#program-x-section-settings
All parameters aren't interpreted or sent to a shell. This means that you can't insert conditionals generally in parameters in your supervisord.conf.
If your goal is to just use different users on say different platforms or one for development and another on a deploymentserver I suggest creating a dedicated user for the service.
If your goal is to only sometimes run as superuser I suggest always using user=root in your supervisord.conf and wrapping your program in a small shell script that interprets this environment variable and drops privileges accordingly.
This other SO question might help you:
https://unix.stackexchange.com/questions/132663/how-do-i-drop-root-privileges-in-shell-scripts
I have used "rebar generate" to create the package and move package to the test pc for running.
But when running the common test suite, I don't know how to "-env ERL_LIBS XXX" with "ct_run" command.
How to correct it?
ct_run -dir /home/peter/gate-0.0.1.20/lib/gate-0.0.1.20/ct -suite gate_test_data_SUITE.erl -erl_args -- -env ERL_LIBS gate-0.0.1.20/lib
This variable also works for the environment. Have you tried running the command as ERL_LIBS gate-0.0.1.20/lib ct_run -dir /home/peter/gate-0.0.1.20/lib/gate-0.0.1.20/ct -suite gate_test_data_SUITE.erl ?