The Dev Blog

Putting Family Management on Rails!

Retrieving Files With Capistrano

Posted by Guy Naor Thu, 23 Nov 2006 08:13:00 GMT

I had today an interesting problem - how do I retrieve a file from a server using capistrano. First an answer to questions I know I'm going to have to answer...

Why with capistrano? Becuase it's VERY easy to do with capistrano. We just need a small addition to it. And most important, the connections to the servers and the ability to run commands are already there in capistrano, making it easy to automate the tasks. One cap command instead of multiple shell commands.

So as an example, I want to retirieve a database dump and some files from the server, in order to test stuff on the development machines. Capistrano doesn't have a get, it only has a put. And for a good reason. First of all, this isn't a common task, and second, how do you retrieve the same file from multiple servers? What about overwriting?

So first we lay some ground rules. We will retrieve from one server only (though it's easy to make it work for multiple, but it won't be generic). To make sure it's run on one server, we'll mark the server as primary. Just like for a database. But we'll do it for an app server. We will create a local directory to save the files into. We also create a temp directory on the server to store the files we will retrieve.

In the area of deploy.rb that has all the server definition, define the main app server:

role :app, "app.test.com", :primary => true

And create a new task:

desc "Get database dump and uploaded files from the server"
task :retrieve_content, roles => :app, :only => { :primary => true } do
  cont_dest  = "tmp_content"

  # Add your rollback here...

  transaction do
    system("mkdir -p #{cont_dest}") # Create a directory for storing the files
    # Prepare the backup
    run <<-CMD
      mkdir -p ~/#{cont_dest} &&
      pg_dump -d test_production -U tester -c > ~/#{cont_dest}/backup.sql &&
      tar -C #{deploy_to}/current/public/uploads/ -czf ~/#{cont_dest}/uploads.tar.gz .
    CMD

    # Now we retrieve the files...
    execute_on_servers(options) do |servers|
      puts "    >> Retrieving remote files into #{cont_dest}"

      # Here is the important "magic": we retrieve the current SSH session
      # belonging to our server (remember, we have one server only so we use servers[0])
      # then we create on top of that session an sftp session and use get_file to retrieve the files
      self.sessions[servers[0]].sftp.connect do |tsftp|
        tsftp.get_file "#{cont_dest}/backup.sql", "#{cont_dest}/backup.sql"
        tsftp.get_file "#{cont_dest}/uploads.tar.gz", "#{cont_dest}/uploads.tar.gz"
      end
    end

    # For cleanup we remove the remote files
    delete "~/#{cont_dest}", :recursive => true
  end
end

Now that the basics are there, go and retrieve whatever you want from the server. And see how cool it is with capistrano, where I just have to type

cap retrieve_content
and everything is run on the remote server like it should, then brought over to my dev machine.

Posted in  | no comments

del.icio.us:Retrieving Files With Capistrano digg:Retrieving Files With Capistrano spurl:Retrieving Files With Capistrano wists:Retrieving Files With Capistrano simpy:Retrieving Files With Capistrano newsvine:Retrieving Files With Capistrano blinklist:Retrieving Files With Capistrano furl:Retrieving Files With Capistrano reddit:Retrieving Files With Capistrano fark:Retrieving Files With Capistrano blogmarks:Retrieving Files With Capistrano Y!:Retrieving Files With Capistrano smarking:Retrieving Files With Capistrano magnolia:Retrieving Files With Capistrano segnalo:Retrieving Files With Capistrano

Comments

Comments are disabled

Subscribe to The Dev Blog