How to setup gsutil to run from Anacron? - google-cloud-storage

As user, gsutil works nice.
gsutil works nice when called from crontab (user).
As root, gsutil says:
Caught non-retryable exception while listing gs://....: ServiceException: 401 Anonymous users does not have storage.objects.list access to bucket ...."
gsutil does not work when called from Anacron (root).
Other scripts called from Anacron run nice.
The ~/.boto file contains credentials, and is located in user HOME directory.
So maybe that is causing the exception.
I tried setting BOTO_CONFIG, but it didn't change results:
$ gsutil -D ls 2>&1 | grep config_file_list
config_file_list: ['/home/wolfv/.boto']
$ sudo gsutil -D ls 2>&1 | grep config_file_list
config_file_list: []
$ BOTO_CONFIG="/root/.boto"
$ sudo gsutil -D ls 2>&1 | grep config_file_list
config_file_list: []
How to setup gsutil to run from Anacron?
$ gsutil -D
gsutil version: 4.22
checksum: 2434a37a663d09ae21d1644f64ce60ca (OK)
boto version: 2.42.0
python version: 2.7.13 (default, Jan 12 2017, 17:59:37) [GCC 6.3.1 20161221 (Red Hat 6.3.1-1)]
OS: Linux 4.9.11-200.fc25.x86_64
multiprocessing available: True
using cloud sdk: True
config path: /home/wolfv/.boto
gsutil path: /home/wolfv/Downloads/google-cloud-sdk/platform/gsutil/gsutil
compiled crcmod: True
installed via package manager: False
editable install: False
Command being run: /home/wolfv/Downloads/google-cloud-sdk/platform/gsutil/gsutil -o GSUtil:default_project_id=redacted -D
config_file_list: ['/home/wolfv/.config/gcloud/legacy_credentials/redacted/.boto', '/home/wolfv/.boto']
config: [('debug', '0'), ('working_dir', '/mnt/pyami'), ('https_validate_certificates', 'True'), ('debug', '0'), ('working_dir', '/mnt/pyami'), ('content_language', 'en'), ('default_api_version', '2'), ('default_project_id', 'redacted')]
UPDATE_1
export BOTO_CONFIG worked for the terminal:
$ sudo -s
[root] # export BOTO_CONFIG=/home/wolfv/.boto
[root] # gsutil -D ls 2>&1 | grep config_file_list
config_file_list: ['/home/wolfv/.boto']
[root] # vi /root/.bashrc
add this line to end of .bashrc:
export BOTO_CONFIG=/home/wolfv/.boto
exit
open new terminal and test the new BOTO_CONFIG in bash.rc
$ sudo -s
[root] # gsutil -D ls 2>&1 | grep config_file_list
config_file_list: ['/home/wolfv/.boto']
exit
Unfortunately export BOTO_CONFIG in /root/.bashrc did not help Anacron call gsutil.
The backup log shows that Anacron called the backup script, and the backup script call to gsutil failed.
Does it matter in which initialization script sets path BOTO_CONFIG?
To make the path permanently accessible to Anacron (root), in which file should set BOTO_CONFIG?:
/etc/profile
/root/.bash_profile
/root/.bashrc
UPDATE_2
My credentials are now invlalid, probably from some change I made.
Here is my attempt at houglum's suggestions for BOTO_CONFIG.
First authorize login to get that out of the way:
$ gcloud auth login
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?redirect_uri=http%3A%2F%2Flocalhost%3A8085%2F&prompt=select_account&response_type=code&client_id=redacted.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fappengine.admin+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcompute+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Faccounts.reauth&access_type=offline
Created new window in existing browser session.
WARNING: `gcloud auth login` no longer writes application default credentials.
If you need to use ADC, see:
gcloud auth application-default --help
You are now logged in as [edacted].
Your current project is [redacted]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
Defining BOTO_CONFIG inline does not work:
$ BOTO_CONFIG=/home/wolfv/.boto gsutil ls
Your credentials are invalid. Please run
$ gcloud auth login
Exporting BOTO_CONFIG does not work:
$ export BOTO_CONFIG=/home/wolfv/.boto; gsutil ls
Your credentials are invalid. Please run
$ gcloud auth login
Sourcing bashrc does not work:
$ ls /home/wolfv/.bashrc
/home/wolfv/.bashrc
$ . /home/wolfv/.bashrc; gsutil ls
Your credentials are invalid. Please run
$ gcloud auth login
UPDATE_3
My credentials work if I remove my credentials from .boto, and use auth login instead (based on Your credentials are invalid. Please run $ gcloud auth login)
$ gcloud auth login redacted#email.com
WARNING: `gcloud auth login` no longer writes application default credentials.
If you need to use ADC, see:
gcloud auth application-default --help
You are now logged in as [redacted#email.com].
Your current project is [redacted-123]. You can change this setting by running:
$ gcloud config set project PROJECT_ID
After using auth login, gsutil works from the terminal:
$ gsutil ls
gs://redacted/
gs://redacted/
gs://redacted/
And the backup script that calls gsutil also works from the terminal:
$ ~/scripts/backup_to_gcs/backup_to_gcs.sh
backup_to_gcs.sh in progress ...
backup_to_gcs.sh completed successfully
However, backup_to_gcs.sh fails when called from crontab.
How to run gsutil from crontab?
UPDATE_4
This is in my anacron file:
1 10 anacron_test_id BOTO_PATH=/home/wolfv/.config/gcloud/legacy_credentials/wolfvolpi#gmail.com/.boto:/home/wolfv/.boto /home/wolfv/scripts/backup_to_gcs/backup_to_gcs.sh
anacron runs the backup_to_gcs.sh script as expected, but the backup fails.
When backup_to_gcs.sh script is called from command line, it works fine.
Probably because gsutil runs as user, but does not run as root:
$ gsutil ls
gs://wolfv/
gs://wolfv-test-log/
gs://wolfv2/
gs://wolfvtest/
$ BOTO_PATH=/home/wolfv/.config/gcloud/legacy_credentials/wolfvolpi#gmail.com/.boto:/home/wolfv/.boto gsutil ls
gs://wolfv/
gs://wolfv-test-log/
gs://wolfv2/
gs://wolfvtest/
$ sudo BOTO_PATH=/home/wolfv/.config/gcloud/legacy_credentials/wolfvolpi#gmail.com/.boto:/home/wolfv/.boto gsutil ls
sudo: gsutil: command not found
$ sudo gsutil ls
sudo: gsutil: command not found
Two days ago root was able to run gsutil.
Since then I used dnf history rollback to uninstall a different software.
Could that have effected gsutil authentication?
UPDATE_5
I followed the instructions on https://cloud.google.com/storage/docs/authentication#gsutilauth
USING SERVICE ACCOUNT
$ gcloud auth activate-service-account --key-file=/home/wolfv/REDACTED.json
Activated service account credentials for: [REDACTED#appspot.gserviceaccount.com]
But still, root could not run gsutil:
$ sudo gsutil ls
sudo: gsutil: command not found
$ gsutil ls -la gs://wolfvtest/test_lifecycle/
CommandException: You have multiple types of configured credentials (['Oauth 2.0 User Account', 'OAuth 2.0 Service Account']), which is not supported. One common way this happens is if you run gsutil config to create credentials and later run gcloud auth, and create a second set of credentials. Your boto config path is: ['/home/wolfv/.boto', '/home/wolfv/.config/gcloud/legacy_credentials/my-project#appspot.gserviceaccount.com/.boto']. For more help, see "gsutil help creds".
The help referse to a page that no longer mentions "auth" https://developers.google.com/cloud/sdk/gcloud/#gcloud.auth
So I have one too many credentials:
$ gsutil -D
...
config_file_list: ['/home/wolfv/.boto', '/home/wolfv/.config/gcloud/legacy_credentials/my-project#appspot.gserviceaccount.com/.boto']
Are any of these credentials used by root (for anacron)?
They are not in the root directory.
Should credintals needed for anacron be in the root directory?
UPDATE_5
I tried again after installing Fedora 26 on How to authorize root to run gsutil?

When you execute BOTO_CONFIG=<value> in the shell, you're not actually defining an environment variable, but rather a local shell variable (see this thread for more details). You want to either define the variable inline with the command:
BOTO_CONFIG=/path/to/config gsutil ls
or first export the BOTO_CONFIG environment variable, then run the gsutil command:
export BOTO_CONFIG=/path/to/config; gsutil ls
EDIT:
I just noticed that in addition to your own $HOME/.boto file, you're relying on gcloud's credentials that get set up from gcloud auth login. When you run this, gcloud creates another .boto file for you, and when you run gsutil from gcloud's wrapper script, it loads that .boto file first, followed by whatever .boto file(s) you specify with either the BOTO_CONFIG or BOTO_PATH environment variable.
If you want to run as root (which the cron job does) and use both those .boto files, you'll need to instead use the BOTO_PATH variable to list them, separated by colons, also making sure the BOTO_CONFIG environment variable is not set (BOTO_CONFIG takes precedence over BOTO_PATH... the gsutil docs mention this briefly):
BOTO_PATH=/home/wolfv/.config/gcloud/legacy_credentials/REDACTED/.boto:/home/wolfv/.boto gcloud ls
EDIT 2:
1) When you get the error "sudo: gsutil: command not found", it means that the root user cannot find the gsutil executable in its PATH. You should use the absolute path to the gsutil executable instead -- from your post, it looks like this is /home/wolfv/Downloads/google-cloud-sdk/platform/gsutil/gsutil.
2) When you activate service account credentials, the gcloud wrapper for gsutil will create a separate .boto file (with a path containing legacy_credentials/myproject#appspot[...]), and prefer to use this one if it's present. It contains the attribute gs_service_key_file, while your other .boto file probably contains gs_oauth2_refresh_token -- loading multiple .boto files with multiple credentials attributes like this will result in the error you're seeing.
If you want to use gcloud to manage your auth credentials, you generally shouldn't put anything under the [Credentials] section of your $HOME/.boto file.

Related

Not able to run yq commands via rundeck job definitions

I installed snap package of yq and it is showing under /home/ubuntu/ I want to convert yaml file to json using yq. I used this command cat file.yaml | yq . -o=json > file.json to convert the file under location /home/ubuntu/ and this command is working when I run via command line.
But if I try to run this same command in bash shell script in my rundeck job definition, its giving below error.
Sorry, home directories outside of /home are not currently supported. See https://forum.snapcraft.io/t/11209 for details
My Rundeck version is Rundeck 2.6.9-1 and it is running on ubuntu 18
Updated Answer:
I reproduced your issue, and it's a snap package limitation (described here and also commented by Charles Duffy in your original question), Rundeck home it's defined at /var/lib/rundeck path.
So, the best way is to uninstall the snap yq package (as root: snap remove yq) and install it in the traditional way:
As root:
Download and put the yq binary in the /usr/local/bin path:
wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
Give it the rights permissions:
chmod a+x /usr/local/bin/yq
Then, your job should work.

What parameter(s) do I have to pass `gsutil` to access a Google Cloud local storage? (storage-testbench)

For test purposes, I want to run the storage-testbench simulator. It allows me to send REST commands to a local server which is supposed to work like a Google Cloud Storage facility.
In my tests, I want to copy 3 files from my local hard drive to that local GCS-like storage facility using gsutil cp .... I found out that in order to connect to that specific server, I need additional options on the command line as follow:
gsutil \
-o "Credentials:gs_json_host=127.0.0.1" \
-o "Credentials:gs_json_port=9000" \
-o "Boto:https_validate_certificates=False" \
cp -p test my-file.ext gs://bucket-name/my-file.ext
See .boto for details on defining the credentials.
Unfortunately, I get this error:
CommandException: No URLs matched: test
The name at the end (test) is the project identifier (-p test). There is an example in the README.md of the storage-testbench project, although it's just a variable in a URI.
How do I make the cp command work?
Note:
The gunicorn process shows that the first GET from the cp command works as expected. It returns a 200. So the issue seems to be inside gsutil. Also, I'm able to create the bucket just fine:
gsutil \
-o "Credentials:gs_json_host=127.0.0.1" \
-o "Credentials:gs_json_port=9000" \
-o "Boto:https_validate_certificates=False" \
mb -p test gs://bucket-name
Trying the mb a second time gives me a 509 as expected.
More links:
gsutil global options
gsutil cp ...

Scaleway scw init Inside Docker Container

I am trying to make the Scaleway CLI installed as part of a docker image I'm building to run Azure Pipelines.
My Dockerfile looks like this:
FROM ubuntu:18.04
# To make it easier for build and release pipelines to run apt-get,
# configure apt to not require confirmation (assume the -y argument by default)
ENV DEBIAN_FRONTEND=noninteractive
RUN echo "APT::Get::Assume-Yes \"true\";" > /etc/apt/apt.conf.d/90assumeyes
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
ca-certificates \
curl \
jq \
git \
iputils-ping \
libcurl4 \
libicu60 \
libunwind8 \
netcat\
docker.io \
s3cmd
# Install Scaleway CLI
RUN curl -o /usr/local/bin/scw -L "https://github.com/scaleway/scaleway-cli/releases/download/v2.1.0/scw-2-1-0-linux-x86_64"
RUN chmod +x /usr/local/bin/scw
# Add config for Scaleway CLI
RUN mkdir -p ./config
RUN mkdir -p ./config/scw
COPY ./config/config.yaml $HOME/.config/scw/config.yaml
RUN scw init
# Add private key for SSH connections
COPY ./config/id_rsa $HOME/.ssh/id_rsa
# Config s3cmd
COPY ./config/.s3cfg $HOME/.s3cfg
WORKDIR /azp
COPY ./start.sh .
RUN chmod +x start.sh
CMD ["./start.sh"]
The key section being:
# Install Scaleway CLI
RUN curl -o /usr/local/bin/scw -L "https://github.com/scaleway/scaleway-cli/releases/download/v2.1.0/scw-2-1-0-linux-x86_64"
RUN chmod +x /usr/local/bin/scw
# Add config for Scaleway CLI
RUN mkdir -p ./config
RUN mkdir -p ./config/scw
COPY ./config/config.yaml $HOME/.config/scw/config.yaml
RUN scw init
The config.yaml file referenced above looks like the following (minus the real values of course):
access_key: <key>
secret_key: <secret>
default_organization_id: <orgId>
default_project_id: <projectId>
default_region: nl-ams
default_zone: nl-ams-1
However, when it executes RUN scw init, the output is Invalid email or secret-key: ''
I have tried without running scw init at all, but then calls to scw fail, saying
Access key is required
Details: Access_key can be initialised using the command "scw init".
After initialisation, there are three ways to provide access_key:
with the Scaleway config file, in the access_key key: /root/.config/scw/config.yaml;
with the SCW_ACCESS_KEY environement variable;
Note that the last method has the highest priority.
More info:
https://github.com/scaleway/scaleway-sdk-go/tree/master/scw#scaleway-config
Hint: You can get your credentials here:
https://console.scaleway.com/account/credentials
Which admittedly is one of the better error messages I've seen, but nonetheless has not helped me. I am going to try the Environment Variable approach, which I suspect may do the trick, but I'd still like to know what I'm doing wrong with this config.yaml file.
Lastly... someone with more rep than me needs to create the tag "scaleway". Hard to reference the actual technology in question when the tag doesn't exist.

Jenkins pipeline with docker: run docker as specific user (embedded postgresql

Hi Stack Overflow community!
I have a maven - java project which needs to be build with jenkins pipelines.
To do so, I've configured the job using the docker image maven:3.3.3. Everything works, except for the fact that I use ru.yandex.qatools.embed:postgresql-embedded. This works locally, but on jenkins it complains about starting Postgres:
2019-02-08 09:31:20.366 WARN 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Possibly failed to run initdb:
initdb: cannot be run as root
Please log in (using, e.g., "su") as the (unprivileged) user that will own the server process.
2019-02-08 09:31:40.999 ERROR 140 --- [ost-startStop-1] r.y.q.embed.postgresql.PostgresProcess: Failed to read PID file (File '/var/.../target/database/postmaster.pid' does not exist)
java.io.FileNotFoundException: File '/var/.../target/database/postmaster.pid' does not exist
Apparently, Postgres does not allow to be run with superuser privileges for security reasons.
I've tried to run as a user by creating my own version of the docker-image and adding the following to the DockerFile:
RUN useradd myuser
USER myuser
And this works when I start the docker image from the server's terminal. But by using jenkins pipeline, whoami still prints 'root', which suggests that Jenkins Pipeline uses run -u behind the schemes, which would overrule the DockerFile?
My pipeline job is currently as simple as this:
pipeline {
agent {
docker {
image 'custom-maven:1'
}
}
stages {
stage('Checkout') {
...
}
stage('Build') {
steps {
sh 'whoami'
sh 'mvn clean install'
}
}
}
}
So, my question: How do I start this docker image as a different user? Or switch users before running mvn clean install?
UPDATE:
By adding -u myuser as args in jenkins pipeline, I do log in as the correct user, but then the job can't access the jenkins-log file (and hopefully that's the only problem). The user myuser is added to the group root, but this makes no differece:
agent {
docker {
image 'custom-maven:1'
args '-u myuser'
}
}
And the error:
sh: 1: cannot create /var/.../jenkins-log.txt: Permission denied
sh: 1: cannot create /var/.../jenkins-result.txt.tmp: Permission denied
mv: cannot stat ‘/var/.../jenkins-result.txt.tmp’: No such file or directory
touch: cannot touch ‘/var/.../jenkins-log.txt’: Permission denied
I have solved the issue in our case. What I did was sudo before the mvn command. Keep in mind that every sh step has his own shell, so you need to do sudo in each sh step:
sh 'sudo -u <youruser> mvn <clean or whatever> -f <path/to/pomfile.xml>'
The user must be created in the Dockerfile. I've created it without password, but I don't think it matters since you are root...
You must use sudo instead of switching user or something since otherwise you need to provide a password.
This is far from a clean way... I would suggest to not mess with user-switching unless you really need to (like to run a embedded postgres)
#Thomas Stubbe
I got almost the same error as you mentioned above. I also have an image which has postgresql on it. On the Dockerfile I have created an user named like tdv, and use id command on Container check tdv permission was 1000:1000. I can Start the Container though Jenkins pipeline but it failed to execute sh command, even I add sudo -u tdv for each command. Did you did any other configuration?
My Jenkins Pileline script like following:
pipeline{
agent none
stages{
stage('did operation inside container'){
agent {
docker{
image 'tdv/tdv-test:8.2'
label 'docker_machine'
customWorkspace "/opt/test"
registryUrl 'https://xxxx.xxxx.com'
registryCredentialsId '8269c5cd-321e-4fab-919e-9ddc12b557f3'
args '-u tdv --name tdv-test -w /opt/test -v /opt/test:/opt/test:rw,z -v /opt/test#tmp:/opt/test#tmp:rw,z -p 9400:9400 -p 9401:9401 -p 9402:9402 -p 9403:9403 -p 9407:9407 -p 9303:9303 --cpus=2.000 -m=4g xxx.xxx.com/tdv/tdv-test:8.2 tdv.server'
}
}
steps{
sh 'sudo tdv whoami'
sh 'sudo tdv pwd'
sh 'sudo tdv echo aaa'
}
}
}
}
After the Job run, I can check the Container start up actually. but it still get error like following
$ docker top f1140072d77c5bed3ce43a5ad2ab3c4be24e8c32cf095e83c3fd01a883e67c4e -eo pid,comm
ERROR: The container started but didn't run the expected command. Please double check your ENTRYPOINT does execute the command passed as docker run argument, as required by official docker images (see https://github.com/docker-library/official-images#consistency for entrypoint consistency requirements).
Alternatively you can force image entrypoint to be disabled by adding option `--entrypoint=''`.
[Pipeline] {
[Pipeline] sh
sh: /opt/test#tmp/durable-081990da/jenkins-log.txt: Permission denied
sh: /opt/test#tmp/durable-081990da/jenkins-result.txt.tmp: Permission denied
touch: cannot touch ‘/opt/test#tmp/durable-081990da/jenkins-log.txt’: Permission denied
mv: cannot stat ‘/opt/test#tmp/durable-081990da/jenkins-result.txt.tmp’: No such file or directory
touch: cannot touch ‘/opt/test#tmp/durable-081990da/jenkins-log.txt’: Permission denied
touch: cannot touch ‘/opt/test#tmp/durable-081990da/jenkins-log.txt’: Permission denied
Solution
You currently have sh 'sudo tdv whoami'
I think you should add the -u flag after sudo like that:
sh 'sudo -u tdv whoami'

Capistrano deploy:setup works but not deploy:check

Testing capistrano with a simple recipe.
$ cap deploy:setup
* executing `deploy:setup'
* executing "sudo -p 'sudo password: ' mkdir -p /u/apps/ [..]
[..]
deploy:setup works as exprected.
However
$ cap deploy:check
* executing `deploy:check'
* executing "test -d /u/apps/[..]
[..]
When running deploy:check I get the following error:
The following dependencies failed. Please check them and try again:
--> You do not have permissions to write to `/u/apps/
[..]
--> `/u/apps/app/shared is not writable [..]
It seems that capistrano is not using sudo while in deploy:check mode.
I don't get it!
While in deploy:setup the whole directory structure was created by capistrano without any issue?
Why capistrano doesn't use sudo as in deploy:check?
I also ran into this issue and it turned out capistrano was creating all of the folders under the <user> group except for the shared folder. SSH onto your server and do a long listing ls -l. If you see - root - root - for the shared folder, you'll just need to update the permissions on the folder:
sudo chown <user> shared
sudo chgrp <user> shared
I ran into the same issue: the trick is to explicitly configure Capistrano not to use sudo.
You can turn that off in your deploy.rb file with:
set :use_sudo, false
If you need to use sudo, how about using the sudo DSL Action Invocation in your commands:
run "#{sudo} apachectl restart"