How to find the right version of Ruby - ruby

I'm currently working on a build pipeline that uses Jenkins and GitLab to trigger builds for the project. Basically, the build is triggered when someone pushes to the repository. Also, some Ruby scripts are executed as part of the build process. These scripts run some checks on the projects and perform some fixes, like synchronizing an Xcode project with added and deleted files from the source directory - in this case they are not the same.
I'm using several tools to configure the pipeline. The builds run on a machine that is physically located on the build slave. Jenkins is deployed to an AWS machine. For this reason, I used pritunl to connect the two on a virtual network. I can use local IPs to communicate between the machines and SSH is working fine both ways.
When I push to the remote the build starts correctly on the slave, but it fails to complete. However, if I manually access using SSH through the terminal, the build performs fine. This is the output I get from Jenkins:
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- xcodeproj (LoadError)
from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /Users/jenkins/workspace/Core/platform/ios/scripts/pbxsync.rb:58:in `<main>'
As you can see, it fails to require Xcodeproj, causing the build to fail. Still, this only happens if the build is triggered by Jenkins, not manually.
This makes me think that Jenkins is using some different installation of Ruby, or at least a different environment. Basically what I need is to install gems for the same Ruby environment that Jenkins is using, but I don't know which one that is. Any ideas?
Jenkins has a console that runs Groovy scripts on the remote slave. I've been playing with it a bit, but not many conclusions so far. Maybe that helps.
This may be important; this is the shebang I'm using for the Ruby scripts: #!/usr/bin/env ruby
On the terminal, I'm using the same user as Jenkins is to access the slave machine. It's called "jenkins".
One thing I forgot to mention is that the output is telling me the right version: /Users/jenkins/.rvm/rubies/ruby-2.4.0. At least that's the path it's indicating it's trying to load the gem from. So I tried the following:
: /Users/jenkins/.rvm/rubies/ruby-2.4.0/bin/ruby
require 'xcodeproj'
Then I press ctrl+D and get no output - that installation of ruby is finding the gem properly.

If you are using Jenkins Slave plugin to communicate between Jenkins Master and Jenkins Slave, every command that u specify will be run in non-interactive shell. That means that Jenkins will only have access to system ruby in your case.
So if you want to install something that needs to be installed you have to do it in system ruby. You are using rvm so: rvm use system and you can install gem to system ruby.
If you want to use different Ruby version than system ruby you need to add RVM to $PATH for non-interactive shell. Here is basic setup that should help: https://rvm.io/rvm/basics

I finally managed it. As #Cosaquee indicated in another response, it's important to distinguish between interactive and non-interactive shells. The main reason for this is because, depending on how you call SSH, it makes a difference. As the man page indicates:
If command is specified, it is executed on the remote host instead of
a login shell.
This is meaningful, because the Launch Command for the node I have set for Jenkins is this one:
ssh jenkins#x.x.x.x java -jar ~/bin/slave.jar
In the meanwhile, I was logging in with the standard ssh jenkins#x.x.x.x from the terminal, which starts a login shell. It makes sense that I was getting different results because the two shells load different initial scripts. Basically, if you use ssh jenkins#x.x.x.x to login into the machine ~/.bash_profile is loaded, while if you specify a command, such as ssh jenkins#x.x.x.x whatever, then ~/.bashrc is loaded instead. As such, I added this line to ~/.bashrc:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"
Without it I got:
RVM is not a function, selecting rubies with 'rvm use ...' will not
work.
The advantage was that I could now use RVM from the same environment Jenkins was using. The rest is easy:
ssh jenkins#x.x.x.x rvm --default use 2.3
And:
ssh jenkins#x.x.x.x
rvm --default use 2.3
And both are now using the same version of ruby.

Related

Optimal way to install ruby on Docker where base-OS access is required?

I'm trying to install Ruby on Docker (no Rails), but I'm having some issues. I initially tried with RVM, but I had issues with it; after I'd installed it in the usual way, commands such as ruby or gem install aren't recognised, and I understand that RVM is not best practice for a docker environment. I tried building from binary, but that seemed to be missing so many essential things, it seemed to be an exercise in futility.
I've now tried using the official docker ruby:2.5.1 image, however when I attach to this, I get an irb prompt, and am unable to use operating system commands, such as apt-get due to this.
It's essential that I have operating system access - this script will be using a browser through headless Watir webdriver, attaching to Geckodriver, so there are a number of dependencies required that won't be included in the base ruby install.
What's the best way to handle this with Docker?
This will get you on the command-line of the Ruby box:
docker run -it ruby:2.5.1 bash
You'll now be able to run ruby tools as normal, e.g. ruby, irb, gem. As well as regular Debian commands including apt-get.
Suggestion:
If you want to roam around inside a separated environment, you should choose something like Vagrant.
If you are intended to use docker, give a try this approach.
You can place any code in your ruby file whichever you would like to.
$ docker run -it -v $(pwd)/:/data ruby:2.5 ruby -- /data/hello.rb
hello world!

Puppet: How to reload enviroment when installing gem package - rbenv version is not active

I have a running puppet server and want to do following steps on the puppet agent:
download rbenv from git server to /usr/local/rbenv (success)
download ruby-build from git server (success)
create file rbenv.sh in /etc/profile.d, so that on every login then rbenv-environment ist loaded (success)
install a specific ruby version using an exec-resource with rbenv install (success)
activate the specific ruby version using an exec-resource with rbenv global (fail for current login)
install a specific ruby gem (failed because of ruby version dependency)
The problem is, rbenv started from an exec-resource in puppet switches the ruby version in a subshell, and stores that information somewhere. The ruby version for the current shell, where I startet puppet agent --test is not changed. After logging out and in again, the puppet run is successful, because the environment is successfully loaded again.
So my question is: Is there a possibility to run the package provider in a new subshell? Or do I have to use another exec running gem install?
So my question is: Is there a possibility to run the package provider in a new subshell? Or do I have to use another exec running gem install?
No. Providers run in the host Ruby instance. They may launch external commands, including shells, but they themselves are not run that way.
Furthermore, you said,
After logging out and in again, the puppet run is successful, because
the environment is successfully loaded again.
If it really requires logging out and back in to make the rbenv reconfiguration active (which is unclear), then running the provider in a subshell wouldn't be effective anyway. Neither would running gem install via an Exec, unless that Exec also expressly activated the desired Ruby environment.
If you are using Puppet to swap out the system's default Ruby, out from under itself, then you need to be prepared for inconsistent behavior. You may be able to work around it by employing an appropriate Exec to perform the gem installation.
I had this same problem and wrestled for a solution. I wanted my servers to provision successfully from scratch so running provision twice wasn't going to cut it.
I fixed this by adding a symlink to the shim'ed gem. Puppet looks for the gem provider there.
This worked for me...
include rbenv
rbenv::plugin {'rbenv/ruby-build':}
-> rbenv::build { '2.5.3':
global => true,
}
-> file { '/usr/bin/gem':
ensure => link,
target => '/usr/local/rbenv/shims/gem',
}
-> package {'passenger':
ensure => '6.0.1',
provider => gem,
}

Grunt-contrib-sass or the sass gem is not working when using git push

I'm pretty sure I've tracked the issue down to Node.js not seeing Sass, but I have no clue why...
If I push from my laptop using:
git push lamp somebranch:master, the server remotely checks it out fine, runs npm install without error, and starts processing the gruntfile, but then aborts with "remote: Warning: spawn ENOENT Use --force to continue."
However, (after I push from my laptop like above) I can ssh in, cd into my hooks directory and run ./post-receive and it finishes "Done, without errors." I also tried running grunt in the website's root and it also completed without error.
Any ideas as to what might be going on? I'm completely stumped. Should I set paths to the sass gem in the hook? I scrapped down my gruntfile to use the same target locally as well as on the server to rule out the gruntfile. It compiles fine locally, compiles fine on the server, but fails only when using git push lamp somebranch:master.
Some may wonder why I just didn't compile locally and dump the css into the web root from the devel box... perhaps I should. This time though, I really wanted Push-to-deploy all the way through, compiles and all. For anyone attempting the same thing and running into the same problem, this should help.
First off, it probably wouldn't hurt to scrub the system of any versions of ruby and sass that were installed via the distro's package manager. Then I scrubbed any remnants of previous tinkering with rvm implode and removed traces from .bashrc, etc. Next I ran \curl -sSL https://get.rvm.io | bash -s stable --ruby --auto-dotfiles and pressed ctrl-c to fix any errors first. Once the install script was happy, I let it download and install as normal. I did not have to use rvm install n.n.n,rvm use n.n.n, or rvm use n.n.n --default as 2.2.1 was pulled in like I wanted anyway and seemed fine. After rvm had setup ruby, I then ran gem install sass
Now, the end-all-be-all... using PermitUserEnvironment, like had been mentioned here: How to use sshd-config permituserenvironment option was the way to go. I saw that there were security concerns with that method, but it was the only thing that worked and I won't be trying to run limited shells. It is normal behavior for SSH to not allow the env vars when not using a login shell. I assumed, however, that the git hooks had full access to the user's normal vars (with ruby paths, etc.) and that assumption was incorrect. Add PermitUserEnvironment yes to the server's /etc/ssh/sshd_config or the like and restart the ssh daemon. As the user on the server, I ran env and copied that into .ssh/environment and cleaned up what wasn't needed. After that, I did my git push from the devel box and it found and ran the sass compiler just fine.

pod install: command not found when called from bash script

I'm improving the continuos integration of a project. And we decided to take an extra step and start using cocoapods. All the rvm installation is legacy and indeed I have a lot of troubles installing ruby 2.2.0. The thing is that, when I test my build script using terminal it works fine, but when I try to run them without opening a terminal window (called from applescript, jenkins or another ruby script). The command is not found.
Already tried adding the path to .rvm/scripts to the PATH variable in both .bashrc and .bash_profile
Have you try to reconnect the server after you installed the cocoapods? sometimes it doesn't see the new vars till it disconnected and reconnected.
Also make suer that the vars that you see through the terminal are available for jenkins user. you can check that through the slave "Script Console"
If it still don't work, try to set the path in the "execute shell", just before you run the pod install.
This is how it works for me:
echo "Running pod install"
cd ${WORKSPACE}
export LANG=en_US.UTF-8
pod install

How do i use RVM w/ Hudson CI server on Debian?

I'm trying to setup an automated "build" server for my rails projects using Hudson CI. SO far it's able to run specs and do metrics on the code but I have 2 different projects dependent on 2 different versions of ruby. So i'm trying to use RVM to run multiple copies of ruby then switch back and forth in a pre-build step.
I found a couple posts like this one that try and explain how to make this work, but I'm not running a startup script for hudson, it starts on boot which is how it worked out of the box when i installed it via the debian instructions.
The problem seems to be that even though hudson runs under the "hudson" account and that account has rvm installed (and working) when it tries to run a shell based prebuild step to call rvm switch 1.8.7 it fails with the error "rvm: command not found"
Not sure what I'm doing wrong. Hudson is using SH as its shell but i also tried using bash. no luck.
Has anyone gotten this working before in this setup?
edit the "/etc/init.d/hudson" (!) and change the line:
SU=/bin/su
... change to:
SU="/bin/su -"
... and add rvm setup in the /home/hudson/.profile
I had the same symptoms as you.
After a couple of hours of headbanging, check your $HOME environment variable for Hudson (viewable at http://yourserver/hudson/systemInfo).
Under Ubuntu, the Tomcat 6 start script doesn't set $HOME. Somehow, Hudson inherited my $HOME instead!
I added HOME=$CATALINA_HOME to the /etc/init.d/tomcat6 script just under the rest of the ENV declarations, and now it all works. Very annoying issue, to be sure.

Resources