Cant run Ruby script via gem "ssh-net" - ruby

I am using gem net-ssh.
The connection is established. I am able to run some simple scripts(like "pwd", "ls", etc.) successfully, but when I run the "restart" script I get an error.
Here is a snippet:
output = ssh.exec!("cd /home/csrhub/git/csrhub-api; ./bin/restart")
puts "#{output}"
And the output:
./bin/restart:7:in exec': No such file or directory - bundle (Errno::ENOENT)
from ./bin/restart:7:in'
Environment determined as "development" based on the .environment file.
Loading application.yml
And here is the script where the error occurs.
#!/usr/bin/env ruby
require 'yaml'
require_relative '../app/models/environment.rb'
config = Environment.config('application')
exec "bundle exec pumactl --control-url tcp://127.0.0.1:#{config['control_port']} --control-token #{config['control_token']} phased-restart"
Connecting via Putty, when I run the same command it gets executed without any problems.
EDIT
The PATH variable is different when I Putty:
/home/csrhub/.rbenv/shims:/home/csrhub/.rbenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
And when I run with net-ssh PATH is:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

The problem is in your ssh.exec! call. Net::SSH does not use a login shell to run your commands. A login shell is required for Bash to execute .bash_profile.
Since your rbenv setup is in .bash_profile, your exec! call will be missing your full Ruby environment, and therefore running bundle later in you restart script will fail.
The solution should be to manually execute .bash_profile, so that rbenv gets loaded:
output = ssh.exec!("source ~/.bash_profile; ...rest of commands...")
More information and other proposals here:
net-ssh and remote environment

Related

Ruby: 'bundle exec' throws error for all shell commands

In my project, I have a Gem that contains a shell script in its bin folder, let's call the script do_something.sh.
do_something.sh actually executes a ruby script using Jruby command, the script is called ruby_script.rb.
I am trying to call do_something.sh from my project using:
bundle exec do_something.sh
it keeps throwing errors for all shell commands in the script. I erased all the contents of the script and added only one line "echo 'Hello'" and it is still throwing the following error
NoMethodError: undefined method echo' for main:Object
/usr/local/rvm/gems/ruby-2.1.1#projectName/gems/gemName/bin/do_something.sh:10:in'
/usr/local/rvm/gems/ruby-2.1.1#projectName/bin/do_something.sh:23:in load'
/usr/local/rvm/gems/ruby-2.1.1#projectName/bin/do_something.sh:23:in'
Edit#1
All the files has execute permission.
I also tried to put ruby_script.rb in the bin directory where are files are executables (according to a rule in the gemspec file) and tried calling
bundle exec ruby_script.rb
I get the error "bundler: command not found: ruby_script.rb"
bundle exec ruby ruby_script.rb
I get the error "ruby: No such file or directory -- ruby_script.rb (LoadError)"
Why am I getting this error and how can I solve it? I want to be able to either run do_something.sh or ruby_script.rb. Right now, ruby_script.rb is not recognised and do_something.sh does not recognise the commands.
Ok, finally after two days, I was able to make it work.
bundle install installs my GEM and creates a ruby wrapper by default to sh files in the 'bin' directory. So, when I call my script using bundle exec the ruby wrapper gets called first and it calls my script using a ruby 'load' function. This load function expects a ruby file and that is why all my shell script in the file threw errors, because they were expected to be in ruby.
A workaround to this is installing my gem before 'bundle install' using the following command:
gem install --no-wrapper my-gem
Apparently this command disabled creating the ruby wrapper and I was finally able to call the script using bundle execute do_something.sh
Try specifying sh when you run bundle exec. The NoMethodError is from the script being executed in ruby and not sh.
bundle exec sh do_something.sh
In order to make it work. Setting_up_permissions_on_a_script
First: you have to change the mode for the file using chomd +x file_path
Second: Now you can call either by bundle exec file_path or ./file_path
N.B
1: Don't forget to add #!/bin/sh on top of the file.
2: And do check with deploy-a-shell-script-with-ruby-gem-and-install-in-bin-directory will definitely help you.
Hope this help you!
According to Rubygems Specification Reference, executables included in the gem
... must be executable Ruby files. Files that use bash or other interpreters will not work.
In order to to add an executable to a gem please make sure to read the Adding an executable section on Rubygems Guide.
Eventually you'll be able to run the executable like this:
bundle exec do_something
where bundle exec part is optional.

Run a Ruby Script with Python

I have a Ruby Script that when I run in the shell it works (as user):
/home/user/wpscan/$ ruby ./wpscan.rb -u www.mysite.com
However, I'd like to automate this with a function that I created with Python. Here is the python script:
#!/usr/bin/python
import os
wpscan_env = "/wpscan/"
os.chdir(os.environ['HOME'] + wpscan_env)
os.system("ruby ./wpscan.rb -u www.mysite.com")
Notice that the Python script is in a different folder, home/user/python/first.py and this is why I do the os.chdir() function. When I go back to the shell and type:
/home/user/python/$ python first.py
This is the output I get:
Could not find addressable-2.4.0 in any of the sources
Run `bundle install` to install missing gems.
I am using Ubuntu 14.04 and in order to get wpscan to work, it asked me to install Ruby 2.3.0. I did this via RVM.
wpscan.rb has a few dependencies and it seems it's not instantiating them. Also if I'm inside the wpscan folder and do ruby ./wpscan.rb ... it will work. However if I try to do this from the home directory: ruby wpscan/wpscan.rb ... it throws an error:
[ERROR] cannot load such file --typhoeus
[TIP] try to run 'gem install typhoeus' or 'gem install --user-install typhoeus'. If you still get an error, Please see README file or https://github.com/wpscanteam/wpscan
I have no knowledge of Ruby, this is my first real Python script, and I just installed wpscan 2 nights ago. I'm way out of my league here and I need help. Any further question can be elaborated per request.
Most probably, ruby in your python script is not the same as ruby in your shell. This can happen if you e.g. have a default system ruby installed (e.g. from the system packages) and you install another ruby version via RVM.
When using shell, the RVM automatically loads it's environment from the shell init scripts (e.g. ~/.bashrc) and knows which ruby to use from its settings. Whereas your python script does not load any rvm environment (it's not a login shell) and calls the default system ruby.
In that case, you need to explicitly call the correct ruby from the RVM in your python script. You can to it by calling the RVM wrapper:
browse directories under ~/.rvm/wrappers/ and find the correct ruby version and gemset that you want to use
in your python script, call the ruby command from this wrapper directory instead of the plain `ruby, something like:
rvm_ruby = os.environ['HOME'] + "/.rvm/wrappers/ruby-2.3.0-p100#myproject/ruby"
os.system(rvm_ruby + " ./wpscan.rb -u www.mysite.com")
This should fix your problem.
Thats so simple to execute ruby scripts from python...
import os
os.system('ruby filename.rb')
#if you want to store the output in seperate file
os.system('ruby filename.rb > outfilename.txt)

Why does Capistrano run a command differently

I have been noticing some weird stuff with Capistrano lately. But before I can explain that let me provide some head on from where it is exactly coming from.
As a part of updating my crontab on every deployment. I decided to use whenever/capistrano recipe.
But for some reason(not known to me but I see a issue in github describing the same). Every time I attempt to do so I see following error.
"database configuration does not specify adapter"
Important bit. here how the command look like
INFO [a558a04a] Running ~/.rvm/bin/rvm 2.2.2#thrasher do bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db as deploy#x.x.x.x
DEBUG [a558a04a] Command: cd /home/deploy/project-scp/thrasher/releases/20160129130817 && ~/.rvm/bin/rvm 2.2.2#thrasher do bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db
DEBUG [a558a04a] scheduling frequent upload job
scheduling daily upload job
DEBUG [a558a04a] [write] crontab file updated
INFO [a558a04a] Finished in 2.411 seconds with exit status 0 (successful).
Kindly, take a note of the command.
~/.rvm/bin/rvm 2.2.2#thrasher do bundle exec whenever ...
Now, in order to solve this problem. I set the whenever_command, a capistrano variable to look like this.
set :whenever_command,["RAILS_ENV=#{fetch(:stage)",:bundle,:exec,:whenever]
And ...
When I ran the capistrano again, I saw this.
Running /usr/bin/env RAILS=production bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db as deploy#x.x.x.x
DEBUG [b67e3351] Command: cd /home/deploy/project-scp/thrasher/releases/20160129131301 && /usr/bin/env RAILS=production bundle exec whenever --update-crontab thrasher --set environment=production --roles=app,web,db
Command Executed was
/usr/bin/env RAILS=production bundle exec whenever ...
Question:
Why did the 2 time the command did not look like this.
~/.rvm/bin/rvm 2.2.2#thrasher do RAILS_ENV=production bundle exec whenever
Note:
Rails 4.0.4
Capistrano Version: 3.4.0 (Rake Version: 10.5.0)
Ruby ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
Also using
capistrano/rvm
Update:
In accordance with #will_in_wi answer. To solve the whenever issue I also tried doing this.(inside deploy.rb file.)
namespace :deploy do
...
...
before "whenever:update_crontab", "deploy:set_rails_env"
end
Short answer: Placing an environment variable inside the :whenever_command is not the right way to do it. Based on the whenever/capistrano code, you should use :whenever_command_environment_variables.
Remove your :whenever_command and try this instead:
set :whenever_command_environment_variables, -> { { :rails_env => fetch(:stage) } }
Long answer: you are using capistrano/rvm, which does some magic with Capistrano's "command map" to automatically prefix certain commands with ~/.rvm/bin/rvm.... One of those certain commands is bundle, for example. If you change the whenever command to no longer start with :bundle, the mapping will no longer work.
Without seeing your Capfile, you might need to enable some subset of capistrano/rails. That is what will force RAILS_ENV to be set: https://github.com/capistrano/rails/blob/master/lib/capistrano/tasks/set_rails_env.rake

Run `bundle` system command in subfolder

I am attempting to run bundle in a subfolder of my ruby project, but it appears to be running in the context of my initial directory even though I have changed the current working dir to the subfolder.
# change directories and run bundle in a sub directory:
# ruby script.rb
system('bundle')
system('cd sub_folder')
system('bundle')
The bundle command runs successfully but only for the parent folder. Changing directories via system commands does not properly switch the context for bundler, and runs for the parent folders gemfile twice. What am I missing?
Just figured it out:
Dir.chdir('sub_folder') do
Bundler.with_clean_env do
system('bundle')
end
end
Shelling out - Any Ruby code that opens a subshell (like system,
backticks, or %x{}) will automatically use the current Bundler
environment. If you need to shell out to a Ruby command that is not
part of your current bundle, use the with_clean_env method with a
block. Any subshells created inside the block will be given the
environment present before Bundler was activated. For example,
Homebrew commands run Ruby, but don't work inside a bundle:
http://bundler.io/man/bundle-exec.1.html#ENVIRONMENT-MODIFICATIONS
You could try:
# ruby script.rb
Dir.chdir('sub_folder') do
system('bundle')
end

How to setup Whenever gem in production (RVM)

I've one rake task which i want to execute once every day:
in production installed rvm
in schedule.rb i have
set :output, "/home/username/data/public_html/log/cron_log.log"
every 24.hours do
rake "fetch:smth"
end
crontab -l shows me:
MAILTO="my.mail#gmail.com"
PATH="/usr/local/rvm/rubies/ruby-1.9.3-p125/bin/ruby "
#daily cd /home/username/data/www/nameofsite.com && RAILS_ENV=production bundle exec rake fetch:smth
truly, i'm a little bit confused, coz previously i didn't have experience with cron, so plz help.
EDIT #1
i've run rvm env -- path 1.9.3#global
and it gave me:
PATH="/usr/local/rvm/gems/ruby-1.9.3-p125/bin:/usr/local/rvm/gems/ruby-1.9.3-p125#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p125/bin:/usr/local/rvm/bin:$PATH"
and then i've
MAILTO="said.kaldybaev#gmail.com"
PATH="/usr/local/rvm/gems/ruby-1.9.3-p125/bin:/usr/local/rvm/gems/ruby-1.9.3-p125#global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p125/bin:/usr/local/rvm/bin:$PATH"
#daily RAILS_ENV=production rake rate:fetch
and when i run execute, from ISPmanager, it gave me: Exited with return code = 1
the link below says that if the exit error is 1, then there is already a /var/run/cron.pid file. and it's true, but i don't have root privileges
You don't need schedule.rb if you're calling the task from cron. That's handled by the #daily entry in crontab. Just set the logfile name as an environment variable and have the rake task refer to that. You'll probably also need more in your $PATH than just the path to the ruby binary, otherwise bundle isn't going to be found. While you're giving the path to a ruby, you're not actually selecting it for RVM to know what you mean, so it's not going to be able to find the right gemset. RVM provides wrappers which Do The Right Thing for this sort of task - replace bundle exec with /usr/local/rvm/wrappers/ruby-1.9.3-p125 -S bundle exec and it should work.
Hope that gives you some ideas. There's more here.
UPDATE #1
With Edit #1, you've fixed one problem and created another. You still need to cd to the app directory, otherwise rake won't find the Rakefile.

Resources