This post originated from an RSS feed registered with Ruby Buzz
by Guy Naor.
Original Post: Retrieving Files With Capistrano
Feed Title: Famundo - The Dev Blog
Feed URL: http://devblog.famundo.com/xml/rss/feed.xml
Feed Description: A blog describing the development and related technologies involved in creating famundo.com - a family management sytem written using Ruby On Rails and postgres
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}docont_dest="tmp_content"# Add your rollback here...transactiondosystem("mkdir -p #{cont_dest}")# Create a directory for storing the files# Prepare the backuprun<<-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 filesself.sessions[servers[0]].sftp.connectdo|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"endend# For cleanup we remove the remote filesdelete"~/#{cont_dest}",:recursive=>trueendend
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.