one god for different rubies with rvm - ruby

I have two apps on my machine.
Each app (server) has it's own gemset and works on a different ruby version.
I will manage those apps with god which is installed in it's own gemset.
My god config file config.god looks like this:
God.watch do |w|
current_path = "/home/vagrant/server-1"
w.name = "server 1"
w.start = "ruby #{current_path}/simple-server.rb"
w.keepalive
end
God.watch do |w|
current_path = "/home/vagrant/server-2"
w.name = "server 2"
w.start = "ruby #{current_path}/simple-server.rb"
w.keepalive
end
My servers are simply writing the ruby version to a file (/home/vagrant/server-2/simple-server.rb):
require "date"
loop do
# simple console output
puts "Hello on #{RUBY_VERSION}, #{RUBY_PATCHLEVEL}, #{RUBY_PLATFORM}, #{RUBY_RELEASE_DATE}"
# Specify the name of the log file
log_file = File.join File.expand_path( File.dirname(__FILE__) ), "testfile.txt"
# Write the log into the file
File.open( log_file, 'a') do |f|
date = DateTime.now
date = date.strftime("%H:%M:%S")
f.puts "#{date} on #{RUBY_VERSION}, #{RUBY_PATCHLEVEL}, #{RUBY_PLATFORM}, #{RUBY_RELEASE_DATE}"
end
sleep 2
end
I run god with god -c config.god.
The problem is that my apps are not running with the ruby versions which is specified in the .rvmrc.
I have also tried:
~/.rvm/bin/wrapped_god -d config.god -D
rvmsudo ~/.rvm/bin/wrapped_god -d config.god -D
rvmsudo god -d config.god -D
Is there a solution for this case?
EDIT 2012.08.27:
I have changed my god config as follows:
w.start="~/.rvm/bin/rvm in #{current_path} do ruby simple-server.rb"
And it worked.

try:
start="~/.rvm/bin/rvm in #{current_path} do ruby simple-server.rb"

Related

Script to update RVM-based ruby install and gems

A couple searches didn't turn up an obvious way to update my RVM-based ruby and gems so I whipped up the following script. The desire is to get a list of currently installed gems, update to the new ruby, pull those gems forward, then clean out the old versions of everything. I'm posting it here for feedback, since I don't see an easy way to test it and I'm barely competent at ruby and mostly clueless about RVM.
#!/usr/bin/env ruby
module RubyUpdate
def self.cmd(str, cmd)
puts str
retval = %x(#{cmd})
throw(SystemCallError, cmd) unless $? == 0
return retval
end
def self.update
gems = self.cmd %Q(Getting list of installed gems...), %Q(gem list | cut -d ' ' -f 1)
self.cmd %Q(Updating ruby...), %Q(\\curl -L https://get.rvm.io | bash -s stable --ruby)
self.cmd %Q(Reloading...), %Q(rvm reload)
self.cmd %Q(Updating gems..), %Q(gem update #{gems.gsub("\n", " ")})
self.cmd %Q(Cleaning up gems...), %Q(gem cleanup)
self.cmd %Q(Reloading...), %Q(rvm reload)
self.cmd %Q(Cleaning up ruby...), %Q(rvm cleanup all)
end
end
begin
RubyUpdate::update
puts "Update successful!"
rescue SystemCallError => e
puts "Update failed!"
puts e
end
you should use:
rvm get stable
rvm upgrade current ruby

How to change rvm gemset over ssh on os x server

ok
I don't know how to change rvm version over ssh under os x server.
What I do:
Login on server over ssh
run script (below) and catch error
Error: 'rvm is not a funciton, many-many-words'
What I have as script:
use File::Spec;
my $server_directory = File::Spec->catfile($ENV{HOME},'MyProject');
my $exec_file = File::Spec->catfile($server_directory,'run_script.rb');
my $run_ruby_script = qq'bundle exec ruby $exec_file'.' '.join(' ',#ARGV);
# reload bash profile
print qx(source $ENV{HOME}/.bash_profile);
print qx(source $ENV{HOME}/.bashrc);
# reload ruby
print qx(source $ENV{HOME}/.rvm/scripts/rvm);
my $ruby_setup = qq([[ -s "$ENV{HOME}/.rvm/scripts/rvm" ]] && source "$ENV{HOME}/.rvm/scripts/rvm");
print $ruby_setup. "\n";
# change directory
chdir($server_directory);
# configure gemset name
my $version = qx(cat .ruby-version);
chomp($version);
my $gemset = qx(cat .ruby-gemset);
chomp($gemset);
my $change_rvm_gemset = qq(rvm use $version\#$gemset);
print qx($ruby_setup && $change_rvm_gemset);
print qx(rvm current);
Ok, after all.
def exec_via_bash(line)
puts %Q(#{line})
exec = 'bash -c "#{line}"'
puts `#{exec}`
end
def RubySetup
# reload bash profile
homedir = ENV['HOME']
exec_via_bash %Q(source #{homedir}/.bash_profile);
exec_via_bash %Q(source #{homedir}/.bashrc);
# reload ruby
exec_via_bash %Q(source #{homedir}/.rvm/scripts/rvm);
ruby_setup = %Q([[ -s "#{homedir}/.rvm/scripts/rvm" ]] && source "#{homedir}/.rvm/scripts/rvm")
puts ruby_setup
ruby_setup
end
if ARGV.empty?
puts "there is not enough arguments passed. maybe you forget ruby file to exec?"
exit(1)
end
ruby_script_path = ARGV.shift;
exec_file_absolute_path = File.expand_path(ruby_script_path)
unless File.exists? exec_file_absolute_path
puts "file #{exec_file_absolute_path} doesn't exists!"
exit(1)
end
exec_file_directory = File.dirname(exec_file_absolute_path)
exec_bundle = %Q'bundle exec ruby #{exec_file_absolute_path}' + ' ' + ARGV.join(' ')
# change directory
Dir.chdir(exec_file_directory);
# print %x(ls);
# configure gemset name
version = %x(cat .ruby-version).strip;
gemset = %x(cat .ruby-gemset).strip;
change_rvm_gemset = %Q(rvm use #{version}\##{gemset});
ruby_setup = RubySetup()
exec_bash_login_line = [ruby_setup, change_rvm_gemset, exec_bundle].join ' && ';
puts 'exec bash login line: ' + exec_bash_login_line
forced = %Q(bash --login -c '#{exec_bash_login_line}');
puts forced, "\n";
puts %x(#{forced});
ok, this script is not a kind of beauty, but it works well.
Example of usage?
ruby script.rb ~/bla/bla/bla/run_your_program.rb --first_argument --second_argument a,b,c --etc
As I said before:
I've already on the server via ssh.
So, I need to run scripts via launchd.
And I should do it with
# part of launchd worker
<string>bash</string>
<string>-c</string>
<string>ruby ~/PathToCharmScript.rb -r a</string>
P.S:
Please, help me with improvements of this script for others!
Here is a gist: wow_this_works

Run def in ruby program

I'm a beginner in programming and wrote this little program:
Test.rb:
# encoding: utf-8
require 'open-uri'
require 'nokogiri'
def parse_file
doc = Nokogiri::XML(File.open("test.xml"))
parse_xml(doc)
end
def parse_xml(doc)
doc.root.elements.each do |node|
parse_tracks(node)
end
end
def parse_tracks(node)
if node.node_name.eql? 'kapitel'
puts 'New Kapitel'
end
end
I know how to execute this code:
ruby test.rb
But how can I call the def parse_file?
Simply add whatever you want to the end of your file. Ruby scripts are simply scripts, they are being interpreted:
…
end
parse_file # ⇐ HERE YOU GO
You can either call the method at the end of your test.rb file:
def parse_file
# ...
end
parse_file
And run it with
$ ruby test.rb
Or leave the file as it is, require it as a library and call the method manually:
$ ruby -r test.rb -e "parse_file"
Rather than hard-coding your file path, you can pass it as an argument when calling your script. Arguments can be accessed via the ARGV array:
def parse_file(file)
doc = Nokogiri::XML(File.open(file))
parse_xml(doc)
end
parse_file(ARGV.first)
Now you can run it with:
$ ruby test.rb test.xml
Another option is to make the script executable. Add a shebang as the first line of you file:
#!/usr/bin/env ruby
And set the execute flag:
$ chmod +x test.rb
Now you can run it with:
$ ./test.rb test.xml
just add
parse_file
in the end of your ruby file

Running command line commands from Thor executable

In my executable Ruby file I have the following:
#!/usr/bin/env ruby
require 'thor'
include Thor::Actions
class UI < Thor
# def self.source_root
# File.dirname(__FILE__)
# end
desc "makecal", "Generates postscript calendar to your desktop"
def makecal
# puts `ls ~`
puts run('ls ~')
# puts run "pcalmakecal -B -b all -d Helvetica/8 -t Helvetica/16 -S #{Time.now.month} #{Time.now.year} > ~/Desktop/#{Time.now.month}-#{Time.now.year}"
end
end
UI.start
In the terminal when I run the file as is I get an empty line as Thor's run command is returning a NilClass.
However, when I un-comment the puts `ls ~` and comment out Thor's run method I get an output of my home directory as expected.
I'm having trouble figuring out why I can't get Thor's run method to work like Ruby's ticks.
Any ideas where I may have went wrong?
Thanks for looking
I didn't put the include statement inside my class and that messed things up. The code should be:
#!/usr/bin/env ruby
require 'makecal'
class UI < Thor
include Thor::Actions
# def self.source_root
# File.dirname(__FILE__)
# end
#
desc "makecal", "Generates postscript calendar to your desktop"
def makecal
# puts `ls ~`
puts run('ls ~')
# puts run "pcal -B -b all -d Helvetica/8 -t Helvetica/16 -S #{Time.now.month} #{Time.now.year} > ~/Desktop/#{Time.now.month}-#{Time.now.year}"
end
end
UI.start
Thor's documentation on this method is actually wrong and incomplete. It documents that it returns the "contents of the command" (which I assume means the standard output), but it, by defualt, does nothing.
But, you can, apparently, use the :capture option to get what you want:
unless options[:pretend]
config[:capture] ? `#{command}` : system("#{command}")
end
So, try doing
puts run("ls ~", :capture => true)
And see if that does it.

How to configure god/redis for two environments?

I want to use god to monitor my redis server. The problem is that they are in different locations locally and on my server. I tried doing something like this but this causes god to fail.
%w{6379}.each do |port|
God.watch do |w|
w.name = "redis"
w.interval = 30.seconds
if RAILS_ENV == 'development'
w.start = "/usr/local/bin/redis-server /usr/local/bin"
w.stop = "/usr/local/bin/redis-cli -p 6379 shutdown"
else # in production
w.start = "/usr/local/etc/redis-server /usr/local/etc"
w.stop = "/usr/local/etc/redis-cli -p 6379 shutdown"
end
end
end
Use
if ENV["RAILS_ENV"] == 'development'
And then call your script using
RAILS_ENV=development sudo god ...
in your dev environment.
and in production:
sudo god ...

Resources