How to concatenate two string environment /w env stanza in Upstart? - upstart

Here is a part of my .conf file.
env SERVICE_ROOT="/data/service_root"
env LOG_DIR="$SERVICE_ROOT/logs"
and I checked all variables with following..
echo "\n`env`" >> /tmp/listener.log 2>&1
I expect that $LOG_DIR is "/data/service_root/logs" but what I got is..
SERVICE_ROOT=/data/service_root
LOG_DIR=$SERVICE_ROOT/logs
Did I miss something?

Defined environment variable is not accessible to the Job Configuration File itself.
Upstart allows you to set environment variables which will be accessible to the jobs whose job configuration files they are defined in.
As explained in 8.2 Environment Variables:
Note that a Job Configuration File does not have access to a user's environment variables, not even the superuser. This is not possible since all job processes created are children of init which does not have a user's environment.
Defined variable $SERVICE_ROOT is accessible to defined job.
# /etc/init/test.conf
env SERVICE_ROOT="/data/service_root"
script
export LOG_DIR="$SERVICE_ROOT/logs"
# prints "LOG_DIR='/data/service_root/logs'" to system log
logger -t $0 "LOG_DIR='$LOG_DIR'"
exec /home/vagrant/test.sh >> /tmp/test.log
end script
Variable $LOG_DIR exported in script block is available for processes called within the same block.
#!/bin/bash -e
# /home/vagrant/test.sh
echo "running test.sh"
echo "\n`env`" | grep 'LOG_DIR\|SERVICE_ROOT'
After running sudo start test content of /tmp/test.log will be:
running test.sh
SERVICE_ROOT=/data/service_root
LOG_DIR=/data/service_root/logs
In syslog you will find:
Jul 16 01:39:39 vagrant-ubuntu-raring-64 /proc/self/fd/9: LOG_DIR='/data/service_root/logs'

Related

How to run command with preceding variable [duplicate]

This question already has answers here:
PowerShell: Setting an environment variable for a single command only
(10 answers)
Closed 4 years ago.
I know that you can pass environment variables to docker-compose.
docker-compose.yml
. . .
mysql:
image: mariadb:10.2
ports:
- "${DB_PORT}:3306"
. . .
$ DB_PORT=3396 docker-compose up
However this only works using bash. I am using PowerShell and am trying to find an equivalent that is only a one line command.
PS> $env:DB_PORT:3306 docker-compose up does not work. Neither does
multiline
$env:DB_PORT=3396 `
>> docker-compose -up
The error I get is
Unexpected token 'docker-compose' in expression or statement.
If I do it one at a time it does work...
PS> $env:DB_PORT=3396
PS> docker-compose -up
Is there not way to do this in PowerShell when the equivalent in bash is ridiculously simple?
POSIX-like shells such as bash offer a way to set environment variables in a command-scoped way, simply by prepending <varName>=<value> pairs directly to a command, as the following example demonstrates:
$ foo=bar bash -c 'echo "[$foo]"'; echo "[$foo]"
[bar]
[]
foo=bar defines environment variable foo for the bash -c '...' child process only; the next command - echo ... - does not see this variable.
PowerShell has NO equivalent construct.
The best you can do is to define the environment variable of interest first, in a separate statement, using ;, PowerShell's statement separator. Any external utility you invoke thereafter - which invariably runs in a child process - will see it, but note that the environment variable will remain in effect in the current PowerShell session, unless you manually remove it:
# Set the env. variable, call the command that should see it,
# remove it afterwards.
PS> $env:foo = 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $null
[bar]
Note how $env:foo = $null i.e., setting the environment variable to $null is the same as removing it; alternatively, you could all Remove-Item env:foo
If you also want to restore a pre-existing value afterwards:
$env:foo = 'original'
# Temporarily change $env:foo to a different value, invoke the
# program that should see it, then restore the previous value.
& { $org, $env:foo = $env:foo, 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $org }
$env:foo
The above yields:
[bar]
original
showing that while the bash process saw the temporary value, bar, the original value of $env:foo was restored afterwards.
Also note another important difference:
In POSIX-like shells, environment variables are implicitly surfaced as shell variables - they share the one and only namespace the shell has for variables.
By contrast, PowerShell surfaces environment variables only via the $env:<varName> namespace (e.g., $env:foo), which is distinct from the (prefix-less) namespace for PowerShell's own variables (e.g., $foo).

How to load a file from the same directory as the script, in MongoDB shell

I'm running a bash script that executes a javascript file in the Mongo shell:
outerscript.sh
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
LOGDIR=~/logs
LOGFILE=$LOGDIR/outerscript.log
mongo < $SCRIPTPATH/jsscript.js >> $LOGFILE 2>&1
jsscript.js
load(myVars.js);
MongoDB is v4.0.19
The script may be run locally or on a remote server, and it may be run from the command line or from a cron job, and I want to load in myVars.js which is always in the same folder as outerscript.sh.
I can't find a way to load myVars.js when running outerscript.sh from a cron job.
pwd() returns the user's home directory, not the location of the currently running script, so this doesn't work for the cron job:
load(pwd() + '/myVars.js');
This also doesn't work for the cron job, I'm guessing for the same reason:
load('./myVars.js');
Alternatively, is there another way to pass variables into my JavaScript file, that will still let me log output to the logfile? As far as I can tell, you can't combine --eval with logging output to a file, and I haven't found a way to read environment variables directly from inside the JS file.
Thanks!
You don't need a redirect, try mongo $SCRIPTPATH/jsscript.js >> $LOGFILE 2>&1
See
$ mongo --help
MongoDB shell version v4.4.1
usage: mongo [options] [db address] [file names (ending in .js)]
db address can be:
foo foo database on local machine
192.168.0.5/foo foo database on 192.168.0.5 machine
192.168.0.5:9999/foo foo database on 192.168.0.5 machine on port 9999
mongodb://192.168.0.5:9999/foo connection string URI can also be used
You can use cat() in your js script.
e.g.
echo '{"path": "some folder"}' > /tmp/foldername.js
Then in your js script:
var txt = cat("/tmp/foldername.js")
var folderObj = JSON.parse(txt)
Then you can use folderObj object in your script.
Why do you not simply use SCRIPTPATH="$(dirname "$0")"?
Wernfried Domscheit answered my question perfectly and I have accepted that answer.
I also worked out how to pass in environment variables as parameters and am posting it here just in case it helps anybody.
outerscript.sh
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
ENVVARS='var mongoAddress='\'"${MONGO_ADDRESS}"\''; var databaseName='\'"${DATABASE_NAME}"\'
mongo --eval "${ENVVARS}" $SCRIPTPATH/jsscript.js >> $LOGFILE 2>&1
jsscript.js
print(mongoAddress);
print(databaseName);

How to access the value of SECRETS in Github Actions?

I'm trying to access the value of SECRETs sent to a GitHub Action, but I'm struggling. The values are returned as [FILTERED] every time, no matter what the key or the original value is.
I can access ENVIRONMENT VARIABLES without a problem, so I must be screwing up somewhere else.
Essentially, what I'm trying to do is send an ssh key to my action/container, but I get the same issue when sending any other key/value as a secret.
My (simplified) GitHub Action is as follows:
action "Test" {
uses = "./.github/actions/test"
secrets = [
"SSH_PRIVATE_KEY",
"SSH_PUBLIC_KEY",
]
env = {
SSH_PUBLIC_KEY_TEST = "thisisatestpublickey"
}
}
Dockerfile:
FROM ubuntu:latest
# Args
ARG SSH_PRIVATE_KEY
ARG SSH_PUBLIC_KEY
ARG SSH_PUBLIC_KEY_TEST
# Copy entrypoint
ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh:
#! /bin/sh
SSH_PATH="$HOME/.ssh"
mkdir "$SSH_PATH"
touch "$SSH_PATH/known_hosts"
echo "$SSH_PRIVATE_KEY" > "$SSH_PATH/id_rsa"
echo "$SSH_PUBLIC_KEY" > "$SSH_PATH/id_rsa.pub"
echo "$SSH_PUBLIC_KEY_TEST" > "$SSH_PATH/id_rsa_test.pub"
cat "$SSH_PATH/id_rsa"
cat "$SSH_PATH/id_rsa.pub"
cat "$SSH_PATH/id_rsa_test.pub"
The output of those three cat commands is:
[FILTERED]
[FILTERED]
thisisatestpublickey
As you can see, I can get (and use) the value of the environment variables, but the secrets aren't being exposed.
Anyone got any clues?
Just to update this, I've also simply tried echoing out both the secrets without quotes in entrypoint.sh:
echo $SSH_PRIVATE_KEY
echo $SSH_PUBLIC_KEY
...and in the log, I see the full decrypted content of $SSH_PRIVATE_KEY (ie, the actual contents of my ssh key) while $SSH_PUBLIC_KEY still returns [FILTERED].
So, I can assume that we are able to see the contents of secrets inside of an action, but I don't know why I can see just one of them, while the other returns [FILTERED].
Is it a caching thing, maybe?
I'm just trying to figure out a predictable way to work with this.
As you can see, I can get (and use) the value of the environment variables, but the secrets aren't being exposed.
That's because they're secrets. The Actions output is explicitly scrubbed for secrets, and they're not displayed.
The file contents still contain the secret contents.

Environment variables in Compose using Powershell with only 1 line [duplicate]

This question already has answers here:
PowerShell: Setting an environment variable for a single command only
(10 answers)
Closed 4 years ago.
I know that you can pass environment variables to docker-compose.
docker-compose.yml
. . .
mysql:
image: mariadb:10.2
ports:
- "${DB_PORT}:3306"
. . .
$ DB_PORT=3396 docker-compose up
However this only works using bash. I am using PowerShell and am trying to find an equivalent that is only a one line command.
PS> $env:DB_PORT:3306 docker-compose up does not work. Neither does
multiline
$env:DB_PORT=3396 `
>> docker-compose -up
The error I get is
Unexpected token 'docker-compose' in expression or statement.
If I do it one at a time it does work...
PS> $env:DB_PORT=3396
PS> docker-compose -up
Is there not way to do this in PowerShell when the equivalent in bash is ridiculously simple?
POSIX-like shells such as bash offer a way to set environment variables in a command-scoped way, simply by prepending <varName>=<value> pairs directly to a command, as the following example demonstrates:
$ foo=bar bash -c 'echo "[$foo]"'; echo "[$foo]"
[bar]
[]
foo=bar defines environment variable foo for the bash -c '...' child process only; the next command - echo ... - does not see this variable.
PowerShell has NO equivalent construct.
The best you can do is to define the environment variable of interest first, in a separate statement, using ;, PowerShell's statement separator. Any external utility you invoke thereafter - which invariably runs in a child process - will see it, but note that the environment variable will remain in effect in the current PowerShell session, unless you manually remove it:
# Set the env. variable, call the command that should see it,
# remove it afterwards.
PS> $env:foo = 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $null
[bar]
Note how $env:foo = $null i.e., setting the environment variable to $null is the same as removing it; alternatively, you could all Remove-Item env:foo
If you also want to restore a pre-existing value afterwards:
$env:foo = 'original'
# Temporarily change $env:foo to a different value, invoke the
# program that should see it, then restore the previous value.
& { $org, $env:foo = $env:foo, 'bar'; bash -c 'echo "[$foo]"'; $env:foo = $org }
$env:foo
The above yields:
[bar]
original
showing that while the bash process saw the temporary value, bar, the original value of $env:foo was restored afterwards.
Also note another important difference:
In POSIX-like shells, environment variables are implicitly surfaced as shell variables - they share the one and only namespace the shell has for variables.
By contrast, PowerShell surfaces environment variables only via the $env:<varName> namespace (e.g., $env:foo), which is distinct from the (prefix-less) namespace for PowerShell's own variables (e.g., $foo).

Do special variables maintain their existence in function calls in other required modules?

I'm not a perl expert and I don't quite get how all of perl's scoping rules work.
I'm setting an $ENV{'whatever'} environment variable, then I'm calling a function in another source .pl file and trying to read that ENV entry, and I'm getting nothing back. Docs say everywhere that ENV persists for the current process and any forked children, but is access to the %ENV variable available in other source files?
The source file was included via a 'require' command. Is that the right way to do it, or is there something static (first time in) about how variables are made available when a source file is required?
%ENV is a global, so it is accessible from everywhere in every source file loaded into a process.
%ENV is inherited when a new process is created with a fork but the new process gets its own copy so any changes made in one will not be visible in the other.
If you're loading the other source file with do or require or use then it's being loaded into the same process and it will see the same %ENV.
However if you're loading the new script with system or exec then the new script is loading in a new process and it will get its own copy of %ENV.
From perldoc perlvar:
%ENV
The hash %ENV contains your current environment. Setting a value in
ENV changes the environment for any child processes you subsequently
fork() off.
require-ing a .pl file is not the same as forking a command.
It would be simpler to just set the necessary environmental variables through a Bash wrapper:
$ cat wrapper.sh
#!/bin/bash
export whatever="/usr/bin/some_dir/"; # Set to env
perl script.pl; # Invoke the script
$ cat script.pl
#!/usr/bin/perl
print $ENV{whatever}; # wrapper.sh : "/usr/bin/some_dir/"
# script.pl : ""