how to use sudo command in jenkins exec command
Solution 1
Jenkins cannot print out the result of certain commands that are executed using sudo.
Hence the best way is to simply allow jenkins to ssh as root to perform those same commands without sudo.
- Allow jenkins user to ssh as root without password required.
- Read this on how to have ssh login without password.
- Then, write the command like so:
<exec command="ssh -A ${root-used} 'Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />
Note that ${root-used}
should have a value like root@ipaddress
Solution 2
The user that is sshing in does not have the command available.
If you look at error it connected could not run command and disconnected
By this I don't mean sudo I mean what you have done after sudo
Console/cake init_runners copy_runners_into_initd
It may be that if you actually ssh in as the user and run the above command it works but not via your jenkins script because it may be that you are missing some environment variables that is defined when you ssh in as per normal and get a session.
I would suggest using full paths to everything including:
which sudo
sudo is /usr/bin/sudo
The full path to sudo to rest assured its nothing to do with that.
UPDATED
Hi Kimsia
Thanks for commenting back and now confirming you have a fix, I still think there is something missing from what you have done with sudo since the return message clearly states command not found. To me it would appear that although you ran sudo the path you were actually in could not run console/cake i.e. command not found !
A few things to try if you still wanted to go down the sudo route since I do believe security wise its a lot safer than opening root ssh access.
- run sudo with -i to take on root's profile and then actually change directory to where Console folder and cake command reside.
<exec command="ssh -t -t -A ${host-used} 'sudo -i cd /path/to/cakephp/app; Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
- Would it not be possible to write a shell script which sudo's in
#!/bin/bash function ssh_and_run_cake() { echo "Working on $hostname --- $instance --::" $ssh -t $hostname "sudo su -i ' echo \"CD Folder run cake init -----------------\"; cd /path/to/cakephp/app; Console/cake init_runners copy_runners_into_initd; echo \"All done------------------------\"; '"; } function rollout_cake() { #for hostname in ${h[@]}; do hostname="yourhost" ssh_and_run_cake # done }
rollout_cake
and from jenkins web interface use the execute shell script which should then call this script and carry out what you want.
I have seen Jenkins work away fine with this method
Updated the shell script to work so long as you define hostname in 2nd function.
You would then need to use jenkins web front end deploy options to execute shell script and define the fullpath script. The script should be on the local file system of jenkins server
Solution 3
I don't think you need to specify your host twice.
<exec command="ssh -t -t -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
<echo msg="${result}" />
Related videos on Youtube
Kim Stacks
I build end-to-end workflow solutions to process data such as BOQ (Bill of Quantities) for businesses in telecomms, civil engineering, and construction.
Updated on June 25, 2022Comments
-
Kim Stacks almost 2 years
I am using jenkins to run my builds.
One of my steps is to copy over certain files and place them inside /etc/init using sudo
<exec command="ssh -A ${host-used} '/etc/init.d/ConvertDaemon stop'" outputProperty="result" escape="false"> </exec> <echo msg="${result}" /> <exec command="ssh -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" /> ${host-used} returns www-data@ip-address
The issue is the 2nd command.
When I run the 1st command, i can see my result printed out in the console log in jenkins.
For the 2nd command, I get a
no tty present
messageSo I changed the 2nd command to
<exec command="ssh -t ${host-used} -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />
I get a
Pseudo-terminal will not be allocated because stdin is not a terminal
How do I overcome this?
UPDATE:
I tried this as well.
<exec command="ssh -t -t ${host-used} -A ${host-used} 'sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" /> <echo msg="${result}" />
I got:
bash: www-data@ipaddress: command not found Connection to ipaddress closed.
I want to emphasize that the command is correctly used. BUT I cannot read the message.
UPDATE2:
There are times when you ask a question, but then you realize the question you want to ask is not the REAL question you want to solve.
This question is like that.
All I wanted to do is to execute a few commands run by jenkins and see the print out of the commands. These commands happen to require sudo.
Jenkins basically ssh as another user www-data to perform these commands.
I was having trouble with printing out the results in jenkins for those commands requiring sudo.
Having spent a lovely saturday working on this with some very helpful SO answers, I realized that I could simply try to execute those commands without sudo by having jenkins ssh as root instead.
It worked.
I am going to answer this question with that approach instead because that is all I wanted -- execute some commands inside jenkins and see their print out.
-
Aaron Golden over 10 yearsLooks like you might need an extra -t argument on your ssh command, per the answer to this question: stackoverflow.com/questions/7114990/…
-
-
Kim Stacks over 10 yearsi tried this and the jenkins hanged here for a very long time
-
konsolebox over 10 years@kimsia It probably really needs an input. It could wait forever if it doesn't get anything it needs. You can try
<exec command="ssh -t -t -A ${host-used} 'screen -dm sudo Console/cake init_runners copy_runners_into_initd'" outputProperty="result" escape="false" />
. -
Kim Stacks over 10 yearsi tried renaming sudo to /usr/bin/sudo. I get back the same result :(
-
Kim Stacks over 10 yearsi tried ssh -t -t -A ${host-used} 'screen -dm it still hanged
-
Kim Stacks over 10 yearsi tried ssh -t -t ${host-used} -A ${host-used} 'screen -dm. It did not hang but also unable to generate the result.
-
konsolebox over 10 yearsI'm not really sure why you had to specify the host twice. Try to not add the -d option to screen. Just use -m.
-
Kim Stacks over 10 yearsthanks for your answer. but i tried an entirely different approach and i got what i wanted. Cheers!
-
Kim Stacks over 10 yearsthanks for your answer. but i tried an entirely different approach and i got what i wanted. Cheers!
-
V H over 10 yearsGlad you have it working, if you are still experimenting please read my updated answer
-
Kim Stacks over 10 yearsssh -t -t -A ${host-used} for some reason this causes my jenkins to hang a long time
-
Kim Stacks over 10 yearsA few things to try if you still wanted to go down the sudo route since I do believe security wise its a lot safer than opening root ssh access. <-- I agree with this. But right now, I need something that works. Can you explain your 2nd solution with more detail? I don't understand by write a shell script which sudo's in and from jenkins web interface
-
Kim Stacks over 10 yearsI still am, @vahid. If there is something better and more secure, I will adopt it.
-
fduff almost 10 yearsyou should edit the sudoers file using the
$ sudo visudo
command instead.