<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>The Dev Blog: Retrieving Files With Capistrano</title>
    <link>http://devblog.famundo.com/articles/2006/11/23/retrieving-files-with-capistrano</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Putting Family Management on Rails!</description>
    <item>
      <title>Retrieving Files With Capistrano</title>
      <description>&lt;p&gt;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... &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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?&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;In the area of deploy.rb that has all the server definition, define the main app server:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;role&lt;/span&gt; &lt;span class="symbol"&gt;:app&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;app.test.com&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:primary&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And create a new task:&lt;/p&gt;

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;desc&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Get database dump and uploaded files from the server&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="symbol"&gt;:retrieve_content&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;roles&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:app&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:only&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:primary&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;cont_dest&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;tmp_content&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

  &lt;span class="comment"&gt;# Add your rollback here...&lt;/span&gt;

  &lt;span class="ident"&gt;transaction&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;system&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;mkdir -p &lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt; &lt;span class="comment"&gt;# Create a directory for storing the files&lt;/span&gt;
    &lt;span class="comment"&gt;# Prepare the backup&lt;/span&gt;
    &lt;span class="ident"&gt;run&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="constant"&gt;CMD&lt;/span&gt;&lt;span class="string"&gt;
      mkdir -p ~/&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt; &amp;amp;&amp;amp;
      pg_dump -d test_production -U tester -c &amp;gt; ~/&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/backup.sql &amp;amp;&amp;amp;
      tar -C &lt;span class="expr"&gt;#{deploy_to}&lt;/span&gt;/current/public/uploads/ -czf ~/&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/uploads.tar.gz .
&lt;/span&gt;&lt;span class="constant"&gt;    CMD&lt;/span&gt;

    &lt;span class="comment"&gt;# Now we retrieve the files...&lt;/span&gt;
    &lt;span class="ident"&gt;execute_on_servers&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;servers&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
      &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;    &amp;gt;&amp;gt; Retrieving remote files into &lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

      &lt;span class="comment"&gt;# Here is the important &amp;quot;magic&amp;quot;: we retrieve the current SSH session&lt;/span&gt;
      &lt;span class="comment"&gt;# belonging to our server (remember, we have one server only so we use servers[0])&lt;/span&gt;
      &lt;span class="comment"&gt;# then we create on top of that session an sftp session and use get_file to retrieve the files&lt;/span&gt;
      &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;sessions&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;servers&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;]].&lt;/span&gt;&lt;span class="ident"&gt;sftp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;tsftp&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
        &lt;span class="ident"&gt;tsftp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get_file&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/backup.sql&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/backup.sql&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
        &lt;span class="ident"&gt;tsftp&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get_file&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/uploads.tar.gz&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;/uploads.tar.gz&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
      &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="comment"&gt;# For cleanup we remove the remote files&lt;/span&gt;
    &lt;span class="ident"&gt;delete&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;~/&lt;span class="expr"&gt;#{cont_dest}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="symbol"&gt;:recursive&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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 &lt;pre&gt;cap retrieve_content&lt;/pre&gt; and everything is run on the remote server like it should, then brought over to my dev machine.&lt;/p&gt;</description>
      <pubDate>Thu, 23 Nov 2006 03:13:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:02e9d7f2-8328-4115-931b-82906755d98d</guid>
      <author>guy.naor@famundo.com (Guy Naor)</author>
      <link>http://devblog.famundo.com/articles/2006/11/23/retrieving-files-with-capistrano</link>
      <category>Rails</category>
    </item>
  </channel>
</rss>
