I want to access a local file which is located on a device via a remote server location via SSH.
The local file is in this directory
/Desktop/applications.csv
and the IP address of the machine it is located in is 192.168.1.1 and user is user1
How do i read it from a remote location using SSH in Ruby on Rails?
I tried doing this but it fails
hash = Digest::MD5.hexdigest(File.read("ssh user#192.168.1.1 /Desktop/applications.csv"))
Not sure how to go about it. Any help appreciated.
Have you looked into SSHKit? It lets you run commands on remote machines, via ssh.
As an example:
require 'sshkit'
require 'sshkit/dsl'
include SSHKit::DSL
on '192.168.1.1'
within "/Desktop/" do
with rails_env: :production do
rake "read_applications"
end
end
end
And the 'read_applications' rake task would do the File.read and whatever else was required.
EDIT:
Does it know what user you're authenticating with? Might need to add the user like this:
on '192.168.1.1'
within "/Desktop/" do
as :user do
# do something
end
end
end
And change :user to be your username. There's loads more examples on the Github page.
Related
Given a model that has an ActiveStorage attachment
class MyObject
has_one_attached :avatar
end
In a dev environment I am able to retrive the avatar as a StringIO object.
obj = MyObject.new( { valid params } )
file = File.open( Rails.root.join( "spec/support/images/test_image.jpg" ))
obj.avatar.attach( io: file, filename: "test_image.jpg" )
obj.save
version = obj.avatar.variant( resize: '200x200>').processed
version_url = Rails.application.routes.url_helpers.url_for( version )
download = open(version_url)
download.class
=> StringIO
When I attempt to do the same think in a test environment, open(version_url) returns
Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
Has anyone managed to successfully download activestorage attachments within a test? How should I configure the test environment to achieve this?
My test environment already has
config.active_storage.service = :test
Rails.application.routes.default_url_options = {host: "localhost:3000"}
What have I overlooked?
EDIT
#storage.yml
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
Stored files are accessed through the Rails application server
Active Storage attachments generate URLs that point to the application. The application URL endpoint then redirects to the real file. This decouples the physical location of the file from the URL and provides indirection which is useful for features such as mirroring.
This also means that in order to access a file using its generated URL, a Rails application server must be running...
Server does not run in test environment
The Rails test suite does not start up a server when running the tests. The tests typically don’t need one in order to run.
Errno::ECONNREFUSED Exception: Failed to open TCP connection to localhost:3000 (Connection refused - connect(2) for "localhost" port 3000)
This error occurs because the open call tries to request the file at the server location localhost:3000. Because there’s no server running, it fails.
Even if you start up a development server, it will still fail because the Active Storage Attachment and Blob records are stored in the test database, not the development database.
Bypass the app server and get a path directly to the file
In order to get access to a file or variant in your test suite, you need to bypass the application server and get a direct path to the file on disk.
The Active Storage test suite source code shows us how to do this:
blob_or_variant.service.send(:path_for, blob_or_variant.key)
View Source
This will return a file path (on disk) which you can then open using File.open.
Fixing the example above
In the example above, change
download = open(version_url) # BAD: tries to access using HTTP
to
download = File.open( version.service.send(:path_for, version.key) )
Use stubs to avoid network requests in the test suite
If you are testing code which accesses files using HTTP, it’s best practice to stub the network call to avoid it altogether.
There’s some good examples of how to do this in RSpec here:
RSpec how to stub open?
I am new here and working on a Rails application that was handed to me for a research project.
I have created my own instance of the project and I am able to access the server running the instance from my computer, BUT, only if I modify my hosts file and map the IP address to an arbitrary domain name.
If I try to access the rails server via an IP address, I get the following error:
"Routing Error
No route matches [GET] "/"
Try running rake routes for more information on available routes."
So my question is, how would I configure the Rails server and application to be accessible via IP address only, for example: http://52.78.233.65:3000/, and why would the server work if I modify the hosts file but not visit the site directly?
If you need remote access, you can choose one of below methods:
Apply in each start
Start rails server by appending -b 0.0.0.0, so command to start rails server is: rails s -b 52.78.233.65 (from your sample IP)
Change default binding option
Modify config/boot.rb by adding below code and start rails server with normal command rails s
config/boot.rb
require 'rubygems'
require 'rails/commands/server'
module Rails
class Server
alias :default_options_bk :default_options
def default_options
default_options_bk.merge!(Host: '0.0.0.0')
end
end
end
a) I'm a ruby in rails beginner developer, and I use windows 7 machine as developement environment...
b) With VirtualBox I just installed, inside the Windows 7 "host", a Linux ubuntu sever "guest", just to run the rails DEVELOPMENT environment ALSO in the linux machine.
c) To do that I configured a virtualbox SHARED FOLDER:
let say I have this shared folder on the host machine (window):
c:\rails\esamiAnatomia
and mounted it on the linux embedded server:
/home/solyaris/host/esamianatomia
d) In this exptended "developement environment" I would like to edit source files with my preferred visual editor on windows (sublime text) and run rails server on linux.
The problem concern database.yml configuration file:
/home/solyaris/host/esamianatomia/config/database.yml
because on Windows I have a database (postgresql) responding port 5433, with specific username/password
but in linux database respond to port 5432, etc.
Questions:
1) It's that "arcgitectural solution ok ? (I mean: developing/editing from a windows 7 host, but running rails server of the linux guest server);
2) There is a way to change/configure database.yml on the fly (I mean: using two different database.yml files: one for the linux machine and anotherone for the window machine) ?
thanks a lot
giorgio
You can technically accomplish 2 if you're not afraid to play around with the guts of Rails. As with any solution that has you accessing internal rails components this may stop working at any time, but fortunately this part of the API is not likely to change often, if ever. Still, use this at your own risk.
Here's how I do it on my projects. First modify your application as follows:
# config/application.rb:
# After require 'rails/all'
require_relative 'db_override'
Then create this new file:
# config/db_override.rb:
case Socket.gethostname
when 'host1'
$db_config = 'config/host1_database.yml'
when 'host2'
$db_config = 'config/host2_database.yml'
else
$db_config = nil # Use the default config/database.yml
end
if $db_config
class DBConfigSelect < Rails::Railtie
initializer "db_config_select", before: "active_record.initialize_database" do
puts "Using custom DB configuration: #{$db_config}"
# Get the existing path configuration
cur_paths = Rails.application.config.paths['config/database'].instance_variable_get :#paths
# Override the default config sources
cur_paths.shift
cur_paths.push $db_config
end
end
end
What you are describing is pretty much the setup that Vagrant is offering, so yeah, you are doing fine, everyone else is also doing it but they didn't set it up themselves (and by that probably get some really nice addons as well, you should take a look at Vagrant).
For your second question: no. Not on the fly. Rails loads the database.yml end then connects to the database with that. When you change it while your Rails server is running, the changes won't get noticed. What you can do however is setup a new environment for your two different machines. Then you can switch between the different environments and depending on the environment, one or the other database gets accessed.
Is it possible to interact with a rails(3) app without going though the http layer? I have some processes running locally on the server, which i'd like to be able to make some changes. Similar to what you can do in the rails console, but in a non-interactive way. I just would just call some ruby scripts to update some records in the database, rather than type them myself in the rails console.
Write these scripts you are talking about, connect via ssh and run them from the bash?!^^
ssh is the secure shell, sth. like telnet but encrytped with ssl if you are no linux user you may dont know about it...
Ahh damn and when you write thes scrips you must do this to get your applications environment:
require 'config/environment.rb'
After requireing the environment file you cann acces all your Models with the script!
If you are just trying to update a bunch of records in the DB, you don't need complete Rails installation. You can write a script and establish connection manually. Something like:
require 'rubygems'
require 'active_record'
class User < ActiveRecord::Base
establish_connection :adapter => "sqlite3", :database => "users.db"
set_table_name "users"
end
User.create(:name => 'a user', :email => 'user#example.com')
And call this from cron the way you want.
Try writing a custom rake task.
Place a file, say, task.rake in your lib/tasks directory. In that file, define a task:
task :mytask => :environment do
#code here
end
and call it from the command line:
> rake mytask
What im trying to do:
service-hosted rails app ( heroku or something )
user logs into application and wants to " DO THINGS "
" DO THINGS " entails running commands to the local machine i have here in my apartment
I've SSHed into a server before ... but i think this would be best setup if the server initiates the connection
I'm FAIRLY running a permanent SSH isnt the best idea
I'm not 100% sure on the process .. i just need information transfer between my hosted application .. and my local machine.
ruby socket set of commands which could possibly work?
any particular gem that would handle this?
Thanks ahead of time!
so far it looks like NetSSH is the answer im looking for
at command prompt:
$ gem install net-ssh
Next we create a new controller file:
app/controllers/ssh_connections_controller.rb
and inside ssh_connections_controller.rb file place:
def conn
Net::SSH.start( '127.0.0.1','wonton' ) do |session|
session.open_channel do |channel|
channel.on_close do |ch|
puts "channel closed successfully."
render :text => 'hits'
end
puts "closing channel..."
channel.close
end
session.loop
end
end
... and substitute your local settings...
'wonton' would be the name of whatever user you want to SSH in as
more to be updated!