How to Run "docker exec -it <container_name > bash" using Gradle Build? - shell

I want to run " docker exec -it bash -c './tmp/script.sh' " this command using gradle from build.gradle. But this command does not work though "docker ps -a" command works fine
I tried in different way, but no luck
1) "docker-compose exec resin_container bash -c './resin/bin/resin-shutdown.sh'".execute().waitFor()
2) CommandLine "docker-compose exec resin_container bash -c './resin/bin/resin-shutdown.sh'"
3) exec{
executable = 'sh'
args "docker-compose exec resin_container bash -c './resin/bin/resin-shutdown.sh'"
}
Full code on build.gradle are as bellow
task dockerDeploy(dependsOn: 'tarArtifact') {
group = "dev"
description = 'Create exploded-war, tar it and deploy to docker'
doLast {
if (devEnvironment) {
if ("docker inspect -f '{{.State.Running}}' resin_container".execute().text.contains('true')) {
println "SHUTTING DOWN Resin Service"
"docker-compose ps".execute().waitFor()
//"docker-compose exec resin_container bash -c './resin/bin/resin-shutdown.sh'".execute().waitFor()
def resin_shutdown = "docker exec -it resin_container bash -c \"./resin/bin/resin-shutdown.sh\""
println "${resin_shutdown}"
exec{
//commandLine = 'docker ps'
commandLine = resin_shutdown
}
println "RESTARTING resin_container"
"docker-compose restart resin_container".execute().waitFor()
} else {
println "STARTING services"
"docker-compose up -d".execute()
}
}
}
}
Expected result like bellow . In here I run the command from shell terminal, but I want to run the same command using gradle build
uzzal$ docker exec -it resin_container bash -c "./resin/bin/resin-
shutdown.sh"
+ GREEN='\033[1;32m'
+ NC='\033[0m'
+ echo 'NODE_NAME : '
NODE_NAME :
+ pushd .
+ echo 'Waiting for server to stop'
Waiting for server to stop
+ sleep 3
+ pgrep -fl -U 999 resin.jar
+ awk '{ print $1 }'
+ xargs kill -SIGTERM
+ sleep 3
+ echo -e '\033[1;32m DONE SHUTTING DOWN \033[0m '
DONE SHUTTING DOWN
+ popd
uzzal$
But Output comes as
FAILURE: Build failed with an exception.
What went wrong:
Execution failed for task ':app:shutResin'.
A problem occurred starting process 'command 'docker exec -it resin_container bash -c "./resin/bin/resin-shutdown.sh"''
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

Related

EOF: command not found in Jenkins Pipeline

I'm trying to launch Datadog agent in Jenkins pipeline, but I'm getting below errors:
line 7: warning: here-document at line 2 delimited by end-of-file (wanted `EOF').
EOF: Command not found Error.
stage('Install Datadog agent'){
when {
environment(name: "DATADOG_REQ", value: "enable")
}
steps {
script {
echo "Installing Datadog Agent"
sh '''#!/bin/bash
ssh -o ConnectTimeout=30 -t ABC#1234 /bin/bash << EOF || error_exit "creating based folder failed for $service_name"
sudo chmod u+x ./${JOB_NAME}/enableDatadogAgent.sh
sudo chown jenkins:jenkins ./${JOB_NAME}/enableDatadogAgent.sh
echo ${DATADOG_REQ} ${JOB_NAME}
./${JOB_NAME}/enableDatadogAgent.sh ${DATADOG_REQ}
EOF'''
}
}
}
Any help would be very helpful.
I changed the << EOF with <<- _EOF_, and now it's working.
script {
echo "Installing Datadog Agent"
sh '''#!/bin/bash
ssh -o ConnectTimeout=30 -t ABC#1234 /bin/bash <<- _EOF_ || error_exit "Failed to execute while doing SSH"
sudo chmod u+x ./${JOB_NAME}/enableDatadogAgent.sh
sudo chown jenkins:jenkins ./${JOB_NAME}/enableDatadogAgent.sh
echo ${DATADOG_REQ} ${JOB_NAME}
./${JOB_NAME}/enableDatadogAgent.sh ${DATADOG_REQ}
_EOF_'''
}

Way to pass a script as a docker build argument?

I want to pass a multi-line script as a argument to docker build command, something like that:
docker build -t tertparam --build-arg load_cat_agent=true --build-arg deploy_cat_script='
echo "aaa";
echo "bbb"
' --no-cache .
and execute it during build, my Dockerfile is like
FROM python:3-alpine
ARG load_cat_agent
ARG deploy_cat_script
ADD . /root/
WORKDIR /root/
RUN if [ $load_cat_agent == "true" ]; then \
$deploy_cat_script;\
fi
CMD /root/start.sh && /root/wait.sh
but i found that it always just print
Step 6/7 : RUN if [ $load_cat_agent == "true" ]; then $deploy_cat_script; fi
---> Running in 7868c310e8e5
"aaa" echo "bbb"
how can i do that?
One way is to write the build args to shell script and then run the shell script.
FROM python:3-alpine
ARG load_cat_agent
ARG deploy_cat_script
ADD . /root/
WORKDIR /root/
RUN echo $deploy_cat_script > ./deploy_cat_script.sh
RUN chmod +x ./deploy_cat_script.sh
RUN if [ $load_cat_agent == "true" ]; then \
./deploy_cat_script.sh;\
fi
CMD /root/start.sh && /root/wait.sh
output:
Step 8/9 : RUN if [ $load_cat_agent == "true" ]; then ./deploy_cat_script.sh; fi
---> Running in 08a2f528a14d
aaa
bbb
If you have two images that are so different that the commands you need to build them are different, it's better to just have two separate Dockerfiles. The docker build -f command can specify which Dockerfile to use, and the Docker Compose build: block has a similar dockerfile: option.
# Dockerfile
FROM python:3-alpine
WORKDIR /root/
ADD . ./
CMD ["/root/start.sh"]
# Dockerfile.deploy
FROM python:3-alpine
WORKDIR /root/
ADD . ./
RUN echo "aaa" \
&& echo "bbb"
CMD ["/root/start.sh"]
If you don't mind needing to run docker build multiple times, you can have one image be built FROM the other. It will inherit its filesystem and metadata settings like the default CMD.
# Dockerfile.deploy, version 2
FROM tertparam
RUN echo "aaa" \
&& echo "bbb"
docker build -t tertparam .
docker build -t tertparam-deploy -f Dockerfile.deploy .
In your original example you might be able to get away with eval the string, but that setup is complex enough that you'll need to script it anyways, so the Dockerfile-based approach probably isn't any more difficult.
The problem with $deploy_cat_script is that shell expansions are detecting command separators before variable expansions. One solution is to use eval. Make sure to learn about [eval command and security issues associated with it](Eval command and security issues).
Dockerfile:
FROM python:3-alpine
ARG load_cat_agent
ARG deploy_cat_script
RUN set -x && if [ "$load_cat_agent" == "true" ]; then \
eval "$deploy_cat_script"; \
fi
With something more complicated such as deploy_cat_script='for i in a b c; do echo $i | sed "s/^/test: /"; done' executes like so:
$ docker build -t tertparam --build-arg load_cat_agent=true --build-arg deploy_cat_script='for i in a b c; do echo $i | sed "s/^/test: /"; done' .
Sending build context to Docker daemon 7.168kB
Step 1/4 : FROM python:3-alpine
---> 59acf2b3028c
Step 2/4 : ARG load_cat_agent
---> Using cache
---> 6e383d31f589
Step 3/4 : ARG deploy_cat_script
---> Using cache
---> 04fc43723e0f
Step 4/4 : RUN set -x && if [ "$load_cat_agent" == "true" ]; then eval "$deploy_cat_script"; fi
---> Running in 72e46c08072e
+ '[' true '==' true ]
+ eval 'for i in a b c; do echo $i | sed "s/^/test: /"; done'
test: a
+ echo a
+ sed 's/^/test: /'
+ sed 's/^/test: /'
+ echo b
test: b
+ sed 's/^/test: /'
+ echo c
test: c
Removing intermediate container 72e46c08072e
---> 765de7cf22a1
Successfully built 765de7cf22a1
Successfully tagged tertparam:latest

Issues while create a file in shell scripting in jenkins pipeline script

I am trying to create a multi line file in Jenkins pipeline script using the below commands.
sh "echo \"line 1\" >> greetings.txt"
sh "echo \"line 2\" >> greetings.txt"
echo "The contents of the file are"
sh 'cat greetings.text'
sh 'rm -rf greetings.txt'
Unforunately , I am not able to create the file named greetings.txt. Can any one please let me know, where I am going wrong.
Results in Jenkins console:
[tagging] Running shell script
+ echo 'line 1'
[Pipeline] sh
[tagging] Running shell script
+ echo 'line 2'
[Pipeline] echo
The contents of the file are
[Pipeline] sh
[tagging] Running shell script
+ cat greetings.text
cat: greetings.text: No such file or directory
Any suggestions would be helpful.
Thanks!
This can be solve this by using single quotes with sh, so you don't need to use escaping. Also you have to create an initial file with > and add content with >>:
pipeline{
agent any
stages{
stage('write file'){
steps{
sh 'echo "line 1" > greetings.txt'
sh 'echo "line 2" >> greetings.txt'
echo "The contents of the file is"
sh 'cat greetings.txt'
sh 'rm -rf greetings.txt'
}
}
}
}
output:
[test] Running shell script
+ echo line 1
[Pipeline] sh
[test] Running shell script
+ echo line 2
[Pipeline] echo
The contents of the file is
[Pipeline] sh
[test] Running shell script
+ cat greetings.txt
line 1
line 2
[Pipeline] sh
[test] Running shell script
+ rm -rf greetings.txt
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
It's not finding a file named greetings.text because you didn't create one (a litte typo in the extension in your cat line). Try sh 'cat greetings.txt', or even better adjusted your script:
sh "echo \"line 1\" >> greetings.txt"
sh "echo \"line 2\" >> greetings.txt"
echo "The contents of the file are"
sh 'cat greetings.txt'
sh 'rm -rf greetings.txt'
If you want to use multiline commands, you can also use this syntax:
sh """
echo \"line 1\" >> greetings.txt
echo \"line 2\" >> greetings.txt
echo "The contents of the file are:"
cat greetings.txt
rm -rf greetings.txt
"""
From the last example, this should generate an output like:
Running shell script
+ echo 'line 1'
+ echo 'line 2'
+ echo 'The contents of the file are:'
The contents of the file are:
+ cat greetings.txt
line 1
line 2
+ rm -rf greetings.txt

Jenkins, how to add variable content to file

How can I add variable content in file?
sh "ssh root#${host} 'echo '$vari' > text.txt'"
This gives empty file
Without variable it works:
sh "ssh root#${host} 'echo some text > text.txt'"
You can use the writeFile command offered by Jenkins:
writeFile file: "text.txt", text: YOUR_VARIABLE
This are 2 ways how you can write the content of a variable to a file:
pipeline {
agent any
environment {
VAR = "hello world!"
}
stages {
stage('Write to file'){
steps{
sh 'echo "${VAR}" > test.txt'
sh "echo ${VAR} >> test.txt"
sh 'cat test.txt'
}
}
}
}
Output:
[test] Running shell script
+ echo hello world!
[Pipeline] sh
[test] Running shell script
+ echo hello world!
[Pipeline] sh
[test] Running shell script
+ cat test.txt
hello world!
hello world!

Shell cmds in Jenkins Pipeline doesnt execute

I want to execute a cURL command, extract Json variable(using jq) & save in variable in Jenkins Pipeline. In Freestyle project under Build when I select Execute Shell and give below commands & I am getting valid Success output with all the values.
,
deployment_info=$(curl -H "Authorization: Basic a123=" "https://api.sample.com/v1")
rev_num=$(jq -r .environment[0].revision[0].name <<< "${deployment_info}" )
env_name=$(jq -r .environment[0].name <<< "${deployment_info}" )
api_name=$(jq -r .name <<< "${deployment_info}" )
org_name=$(jq -r .organization <<< "${deployment_info}" )
declare -r num1=1
pre_rev=$(expr "$rev_num" - "$num1")
echo $rev_num
echo $api_name
echo $org_name
echo $env_name
echo $pre_rev
Now I want to execute the same set of commands in a Pipeline. So this is my Pipeline,
def deployment_info
def rev_num
def env_name
def org_name
def api_name
def pre_rev
def num1
node {
stage('Integration Tests') {
sh "deployment_info=\$(curl --header 'Authorization: Basic abc123=' 'https://api.sample.com/v1')"
sh "rev_num=\$(jq -r .environment[0].revision[0].name <<< \"${deployment_info}\")"
sh "env_name=\$(jq -r .environment[0].name <<< \"${deployment_info}\" ) "
sh "api_name=\$(jq -r .name <<< \"${deployment_info}\" ) "
sh "org_name=\$(jq -r .organization <<< \"${deployment_info}\" )"
sh "declare -r num1=1"
sh "pre_rev=\$(expr \"$rev_num\" - \"$num1\")"
sh "echo $rev_num"
sh "echo $api_name"
sh "echo $org_name"
sh "echo $env_name"
sh "echo $pre_rev"
}
}
The cURL cmd is getting executed & a valid JSON response is seen in console, but after that, I am getting this error,
[Pipeline] sh
[curlpip] Running shell script
++ jq -r '.environment[0].revision[0].name'
+ rev_num=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r '.environment[0].name'
+ env_name=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r .name
+ api_name=null
[Pipeline] sh
[curlpip] Running shell script
++ jq -r .organization
+ org_name=null
[Pipeline] sh
[curlpip] Running shell script
+ declare -r num1=1
[Pipeline] sh
[curlpip] Running shell script
++ expr null - null
expr: non-integer argument
+ pre_rev=
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
ERROR: script returned exit code 2
Finished: FAILURE
Any help is appreciated.

Resources