I am learning Chef and the testing process using Kitchen with the ec2 driver and have the following serverspec file:
require "serverspec"
set :backend, :exec
describe "rbenv" do
describe file("/home/ec2-user/.rbenv") do
it { should be_directory }
end
describe command("rbenv versions") do
its(:exit_status) { should eq 0 }
end
end
When I run kitchen verify amazon-linux the first test passes but the second one fails and causes an error:
rbenv
File "/home/ec2-user/.rbenv"
should be directory
Command "rbenv versions"
exit_status
should eq 0 (FAILED - 1)
Failures:
1) rbenv Command "rbenv versions" exit_status should eq 0
Failure/Error: its(:exit_status) { should eq 0 }
expected: 0
got: 127
(compared using ==)
/bin/sh -c rbenv\ versions
# /tmp/verifier/suites/serverspec/rbenv_spec.rb:11:in `block (3 levels) in <top (required)>'
Finished in 0.05481 seconds (files took 0.30304 seconds to load)
2 examples, 1 failure
Failed examples:
rspec /tmp/verifier/suites/serverspec/rbenv_spec.rb:11 # rbenv Command "rbenv versions" exit_status should eq 0
/opt/chef/embedded/bin/ruby -I/tmp/verifier/suites/serverspec -I/tmp/verifier/gems/gems/rspec-support-3.4.1/lib:/tmp/ver
ifier/gems/gems/rspec-core-3.4.4/lib /opt/chef/embedded/bin/rspec --pattern /tmp/verifier/suites/serverspec/\*\*/\*_spec.rb --c
olor --format documentation --default-path /tmp/verifier/suites/serverspec failed
!!!!!! Ruby Script [/tmp/verifier/gems/gems/busser-serverspec-0.5.9/lib/busser/runner_plugin/../serverspec/runner.rb /tm
p/verifier/suites/serverspec] exit code was 1
>>>>>> Verify failed on instance <default-amazon-linux>.
>>>>>> Please see .kitchen/logs/default-amazon-linux.log for more details
>>>>>> ------Exception-------
>>>>>> Class: Kitchen::ActionFailed
>>>>>> Message: SSH exited (1) for command: [sh -c '
BUSSER_ROOT="/tmp/verifier"; export BUSSER_ROOT
GEM_HOME="/tmp/verifier/gems"; export GEM_HOME
GEM_PATH="/tmp/verifier/gems"; export GEM_PATH
GEM_CACHE="/tmp/verifier/gems/cache"; export GEM_CACHE
sudo -E /tmp/verifier/bin/busser test
']
>>>>>> ----------------------
I logged into the server manually and ran the same command /bin/sh -c rbenv\ versions and it worked fine.
Can anyone tell if there's something I'm doing wrong here?
EDIT 1
I just discovered that when serverspec runs the command the $PATH variable is different from what it is when I log in manually. I added puts ENV['PATH'] to the test and the output was this:
/sbin:/bin:/usr/sbin:/usr/bin
However, when I login manually I get this:
/home/ec2-user/.rbenv/shims:/home/ec2-user/.rbenv/bin:/home/ec2-user/.rbenv/shims:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin
I changed the command in the test to /home/ec2-user/.rbenv/rbenv versions and it passed. Any idea what I need to do to make the paths work correctly here?
EDIT 2
So I've discovered that serverspec is running the commands as root, which means that the changes to ec2-user's path that took place during kitchen converge are unavailable.
I don't know if there's a more idiomatic way to do this with serverspec, but I changed my command to this and the test now passes:
runuser -l ec2-user -c 'rbenv versions'
This allows root to run a command as another user. Unless someone knows of a better way to do this kind of test I'll add this as the answer to the question.
serverspec runs its commands as root, so changes made to any other user's path during convergence are irrelevant.
Using the Linux runuser command will allow root to run a command as another user, thereby gaining access to that user's $PATH:
runuser -l ec2-user -c 'rbenv versions'
Related
I am a newbie and been stuck with this for 2 days; I am about to go crazy.
I am starting to learn Ruby and we got to Rspec.
I installed Rspec with gem install rspec and everything goes ok, but when I execute which rspec I get nothing returned.
When I execute "gem which rspec" I get:
/usr/local/lib/ruby/gems/3.0.0/gems/rspec-3.10.0/lib/rspec.rb
My $PATH is:
[[ -s "$HOME/.profile" ]] && source "$HOME/.profile" # Load the default .profile
export PATH="/usr/local/opt/openssl/bin:$PATH"
export PATH="/usr/local/sbin:$PATH"
alias laptop='bash <(curl -s https://raw.githubusercontent.com/monfresh/laptop/master/laptop)'
export PATH="$HOME/.bin:$PATH"
export PATH="/usr/local/opt/ruby/bin:$PATH"
export PATH="/usr/local/lib/ruby/gems/3.0.0/gems/rspec-3.10.0/lib:$PATH"
And "which ruby" throws:
/usr/local/opt/ruby/bin/ruby
I took a look at these two posts but had no luck with them Post 1
,
Post 2
Any help will be really appreciated!
To simplify, consider following block in a cookbook (cookbook-test) recipe.
79: bash 'Running sudo test sleep command' do
80: user 'root'
81: cwd '/tmp'
82: code <<-EOH
83: sudo sleep 1000
84: EOH
85: end
Running this as
"chef-client -o cookbook-test"
Output:
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '1'
---- Begin output of "bash" "/tmp/chef-script20150813-3835-3kj758" ----
STDOUT:
STDERR: sudo: sorry, you must have a tty to run sudo
---- End output of "bash" "/tmp/chef-script20150813-3835-3kj758" ----
Ran "bash" "/tmp/chef-script20150813-3835-3kj758" returned 1
I added "sudo sleep" just to exemplify usecase. In real case, we run scripts inside above resource block, and these scripts has sudo commands.
After some debugging found that "bash" and "execute" resource blocks both do not have tty allocated to run commands inside them.
Please share your thoughts.
Here's the thing:
Any facility you could use in Chef to run sudo with an allocated tty could also be used by anybody else, which means the requiretty directive in your sudoers is effectively useless. So you might as well just remove it and save yourself the trouble of working around it.
Having said that, here are some ways to work around the problem:
Are you able to ssh to localhost without a password? You could just use ssh -tt localhost sudo somecomand ....
You can use the expect tool, which is designed for controlling terminal-oriented programs. Something like expect -c "spawn sudo somecommand; interact".
You can use screen, with something like screen sudo somecommand.
I am trying to run a ruby script as a service on my centos machine. I can run the ruby script direct from the command line and from a bash file without issue.
However, when I try to run it as a service via /etc/init.d I get the error 'require': cannot load such file -- somegem.
#! /home/user/.rvm/rubies/ruby-2.1.5/bin/ruby
# encoding: utf-8
require "somegem"
I have created an init.d script and placed that in /etc/init.d/
#!/bin/sh
# monitor_endpoint
# chkconfig: 2345 20 80
# Source function library.
. /etc/rc.d/init.d/functions
#Define variables
prog="monitor_endpoint"
exec=/home/user/Workspaces/test/bin/test.rb
echo $exec
start() {
echo -n $"Starting $prog: "
# use daemon to start the service
daemon $exec &
retval=$?
echo
return $retval
}
etc...
Would this be a problem with my gems installation path?
Any help would be much appreciated as this is my first attempt at running a ruby script in this way. Thank you.
the problem is in your environment (the env vars).
run
env
in the normal environment and after that run it from the init script and pipe the output to a file.
look at the differences.
GOing to guess you are missing all the ruby specific stuff(GEM_PATH and all)
Why is command "bundle" not found when using sudo:
[root#desktop gitlab]# sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production
sudo: bundle: command not found
[root#desktop gitlab]#
but does exist when not using sudo:
[root#desktop gitlab]# bundle exec rake gitlab:setup RAILS_ENV=production
Warning
You are running as user root, we hope you know what you are doing.
Things may work/fail for the wrong reasons.
For correct results you should run this as user git.
This will create the necessary database tables and seed the database.
You will lose any previous data stored in the database.
Do you want to continue (yes/no)? no
Quitting...
[root#desktop gitlab]#
The reason I ask is I am following https://github.com/gitlabhq/gitlab-recipes/tree/master/install/centos, and it states to use sudo.
I've tried adding a -i flag as described by Using $ sudo bundle exec ... raises 'bundle: command not found' error, but get "This account is currently not available.".
Check if the PATH has the same values both with and without sudo. Apparently it cannot find bundle just because it is not listed in PATH
You can compare the outputs of following two lines
$ echo 'echo $PATH' | sh
$ echo 'echo $PATH' | sudo sh
Ideally sudo is supposed to leave PATH untouched. But this might be a side issue of your hosting distribution.
Edit by original poster. Output is:
[root#desktop etc]# echo 'echo $PATH' | sh
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root#desktop etc]# echo 'echo $PATH' | sudo sh
/sbin:/bin:/usr/sbin:/usr/bin:/user/local/bin
[root#desktop etc]#
The user was created without a bash login shell. Change this in centos using system-config-users. Then su git into /home/git and move to gitlab directory. Execute the bundle commands without the sudo tag. The next error you will encounter is the missing database.yml in the config dir. fix this with the correct password (i.e. copy the mysql or postgres sample and edit).
I had this issue I thought that my gitlab installed from source and I got same error. but after try Omnibus method for backup my issue solved
with this command:
sudo gitlab-rake gitlab:backup:create
Try :
sudo -u git -H env PATH=$PATH && bundle exec rake gitlab:check RAILS_ENV=production
to use the same PATH than current user.
I'm trying to change the gem source using execute resource but I need to do this just one time.
remove_rubygems = 'gem sources -r http://rubygems.org/'
execute 'change sources to our gem server' do
command "#{remove_rubygems} && gem sources -a http://mygemserver"
creates "~/.gemrc"
end
All this because when I execute this resource many times the .gemrc file look like it.
vagrant#leibniz-app:~$ gem source
*** CURRENT SOURCES ***
http://mygemserver/
http://mygemserver/
http://mygemserver/
http://mygemserver/
...
Then, I want mygemserver one time in the .gemrc file.
How can I do it?
Is there any way to know the content of .gemrc before the execute my resource.?
Don't use ~/ in your path; this is why the creates line was not working to prevent the execute resource from being run when the file already existed.
execute 'change sources to our gem server' do
command "#{remove_rubygems} && gem sources -a http://mygemserver"
creates "/root/.gemrc"
end
Alternately, if you want to check whether the file contains a specific line:
execute 'change sources to our gem server' do
command "#{remove_rubygems} && gem sources -a http://mygemserver"
not_if "grep -F -q -e http://mygemserver/ ~/.gemrc" # this uses a shell, so the
# tilde should work here.
end