1

I need to create a rake task to do some active record operations via a ssh tunnel.

The rake task is run on a remote windows machine so I would like to keep things in ruby. This is my latest attempt.

  desc "Syncronizes the tablets DB with the Server"
      task(:sync => :environment) do
        require 'rubygems'
        require 'net/ssh'

        begin
        Thread.abort_on_exception = true
        tunnel_thread = Thread.new do
          Thread.current[:ready] = false
          hostname = 'host'
          username = 'tunneluser'

          Net::SSH.start(hostname, username) do|ssh|
            ssh.forward.local(3333, "mysqlhost.com", 3306)
              Thread.current[:ready] = true
              puts "ready thread"
              ssh.loop(0) { true }
        end
        end

        until tunnel_thread[:ready] == true do
        end
        puts "tunnel ready"
        Importer.sync

        rescue StandardError => e    
          puts "The Database Sync Failed."
        end
  end

The task seems to hang at "tunnel ready" and never attempts the sync.

I have had success when running first a rake task to create the tunnel and then running the rake sync in a different terminal. I want to combine these however so that if there is an error with the tunnel it will not attempt the sync.

This is my first time using ruby Threads and Net::SSH forwarding so I am not sure what is the issue here.

Any Ideas!?

Thanks

3 Answers 3

2

The issue is very likely the same as here:

Cannot connect to remote db using ssh tunnel and activerecord

Don't use threads, you need to fork the importer off in another process for it to work, otherwise you will lock up with the ssh event loop.

Sign up to request clarification or add additional context in comments.

Comments

0

Just running the code itself as a ruby script (with Importer.sync disabled) seems to work without any errors. This would suggest to me that the issue is with Import.sync. Would it be possible for you to paste the Import.sync code?

2 Comments

The import Sync code is too much to post here but it is basically a modification of this => openmonkey.com/articles/2009/05/importing-legacy-data-in-rails. The modification being it also updates records as well as imports them. It uses two sets of models, one for a local legacy database and one for the db on the server (via the tunnel).
Okay, it should work. I think that the next step is run the script/console and manually execute the command. If you are running Unix, you can also try to snoop the interface in another window to see if there is any sort of traffic. Something like: snoop -i lo port 3333 or tcpdump -i interface name port 3333 Of course, I may have the command wrong - check the man page. If that doesn't help, try seeing if you can do a manual query over that port instead of running the sync. Hopefully it is not some sort of latency (although I would think you would see that running those tasks earlier).
0

Just a guess, but could the issue here be that your :sync rake task has the rails environment as a prerequisite? Is there anything happening in your Importer class initialization that would rely on this SSH connection being available at load time in order for it to work correctly?

I wonder what would happen if instead of having environment be a prereq for this task, you tried...

...
Rake::Task["environment"].execute
Importer.sync
...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.