<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Joao Sa</title>
    <link>https://joaomsa.com</link>
    <atom:link href="https://joaomsa.com/rss.xml" rel="self" type="application/rss+xml" />
    <description></description>
    <language>en-us</language>
    <pubDate>Tue, 15 Nov 2022 09:07:41 +0000</pubDate>
    <lastBuildDate>Tue, 15 Nov 2022 09:07:41 +0000</lastBuildDate>

    
    <item>
      <title>Spotting Deployment Regressions Like A Boss</title>
      <link>https://joaomsa.com/2013/10/22/spotting_deployment_regressions_like_a_boss/</link>
      <pubDate>Tue, 22 Oct 2013 04:13:10 +0000</pubDate>
      <author>me@joaomsa.com (Joao Sa)</author>
      <guid>/2013/10/22/spotting_deployment_regressions_like_a_boss</guid>
      <description>&lt;p&gt;A common work flow I’ve seen some Rails devs settle in seems to include implementing features, fixing application bugs, and whipping up rigorous tests all locally on their machines and only to later cross their fingers hoping it didn’t break on deployment. Since the only good code is shipped code, deployment time eventually comes around and suddenly chaos ensues as neither god, stack traces, or Stack Overflow seem to indicate what exactly is causing the broken deployment (we’ve encountered many just such hard to track down problems with the Rails asset pipeline). DevOps to the rescue!&lt;/p&gt;

&lt;p&gt;We’ve got a wonderdful tool in our hands with &lt;a href=&quot;https://github.com/capistrano/capistrano&quot;&gt;Capistrano&lt;/a&gt;, at least when deployment fails there’s still a nice working build running as Capistrano handles rollbacks to the last working copy gracefully. For debugging these broken builds we could spend hours pouring over documentation looking for some funcional change in all our gem dependencies, blindly altering code until it works again… or break out the power tools and nail this in a matter of minutes.&lt;/p&gt;

&lt;h3 id=&quot;git-bisect&quot;&gt;git bisect&lt;/h3&gt;
&lt;p&gt;Times like these are when you truly see the value of a great version control system like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git&lt;/code&gt;. You could go backwards checking each commit one by one, but that’s too time consuming. We’ll make use of binary search to drastically cut down our possible sample space of breaking commits using &lt;a href=&quot;https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git bisect&lt;/code&gt;&lt;/a&gt;. The bisecting workflow is fairly simple.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git bisect start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For every commit we pass through we mark it as good or bad if it doesn’t exhibit the bug we’re trying to track down. Initially we establish the boundaries of our search, and the current commit where we’re starting from already has a problem so we’ll tag it as such:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git bisect bad
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we have to establish a decent endpoint where we know all was fine. You may not remember it but you sort of have an idea that 20 commits ago everything worked for sure.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git bisect good HEAD~20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You need only have a vague idea of when it last worked.&lt;/p&gt;

&lt;h3 id=&quot;capistrano-local-copy&quot;&gt;capistrano local copy&lt;/h3&gt;
&lt;p&gt;Since we’ll be constantly swapping commits through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git bisect&lt;/code&gt;, it’s imperative to make sure you’re deploying from the commit you checkout last from your local repository, not the tip of some remote branch. Fortunately though, we don’t have to edit our deployment recipes each and every time we change commits. We’ll override a few Capistrano variables in a separate file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Capfile_override&lt;/code&gt; to ensure we’re pushing the right code.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Capfile_override&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;'.'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:scm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;           &lt;span class=&quot;ss&quot;&gt;:none&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy_via&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;    &lt;span class=&quot;ss&quot;&gt;:copy&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:copy_exclude&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%x(git clean -ndX)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
                       &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;sub!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Would remove &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;On every invocation of Capistrano we’ve also got to make sure we’re loading our recipes and variables in the right order, we manually load our files with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-f&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;It’s not particularly wise to try this on a production server and risk unnecessary downtime or database corruption, so spin up a VM and use it as the deploy target. Capistrano also allows us to easily change our deployment machine using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;HOSTS&lt;/code&gt; environment variable.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;HOSTS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;192.168.122.100 cap deploy &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; Capfile &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; Capfile_override
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Don’t forget to adjust the deployment command as necessary in case you use things like bundler or multistage extensions that require additional arguments. For example update your gems with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bundle install&lt;/code&gt; on each run.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;git-bisect-run&quot;&gt;git bisect run&lt;/h3&gt;
&lt;p&gt;The exit code from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cap deploy&lt;/code&gt; tells us exactly whether our deployment was successful or a dud, we’re going to take advantage of that to automatically tag our commits and speed up our search. We can automate this process using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git bisect run&lt;/code&gt;. It takes a script that tests for our bug keeps skipping until it tracks down our culprit.&lt;/p&gt;

&lt;p&gt;Putting it all together.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;HOSTS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;192.168.122.100 git bisect run cap deploy &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; Capfile &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; Capfile_override
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Voila!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;5da18fab84e7cff4b39ceaeebcd2d7c8b88cbe40 is the first bad commit
commit 5da18fab84e7cff4b39ceaeebcd2d7c8b88cbe40
Author: Joao Sa &amp;lt;joao.sa@innvent.com.br&amp;gt;
Date:   Tue Oct 12 11:48:37 2013 -0300

    Updates matross gem

:100644 100644 a1494a...13809 22159...7d779 M    Gemfile
:100644 100644 8aece6...6462d 00899...332cf M    Gemfile.lock
bisect run success
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now that we’ve found our first broken commit a quick diff will point out what caused our breakage.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fingerprint GitHub SSH Public Keys</title>
      <link>https://joaomsa.com/2013/09/22/fingerprint_github_ssh_public_keys/</link>
      <pubDate>Sun, 22 Sep 2013 23:12:10 +0000</pubDate>
      <author>me@joaomsa.com (Joao Sa)</author>
      <guid>/2013/09/22/fingerprint_github_ssh_public_keys</guid>
      <description>&lt;p&gt;When introducing GitHub to new employees sometimes the first thing they encounter are authentication problems. 99% of the time these are one of 2 issues, they haven’t registered their public keys with a GitHub account or their ssh-agent isn’t running with the right private key.&lt;/p&gt;

&lt;p&gt;Both problems are fairly straightforward to debug. When encountering this my first instinct is to check if their ssh-agent is running with a private key.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ssh-add &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Should output something like this, the fingerprint of their public key.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2048 e9:bd:b0:97:d5:3c:b5:d5:6f:fe:9d:aa:76:d3:42:0d joaosa@karp (RSA)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From here if they’ve already generated a key add it to their SSH agent or generate a new one:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ~/.ssh/id_rsa &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;ssh-keygen&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; ssh-add ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;More often though, they may simply have forgotten to register keys with GitHub. 
One of my favorite little known tricks is quickly inspecting a GitHub user’s public keys. You can do it by appending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.keys&lt;/code&gt; to the users profile url. You can see mine at &lt;a href=&quot;https://github.com/joaomsa.keys&quot;&gt;https://github.com/joaomsa.keys&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Problem though is that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh-add -l&lt;/code&gt; returns the ssh-keys in a hex fingerprint while GitHub shows them in their raw glory. In order to generate the hex fingerprint of a public key, we can use the built-in option in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh-keygen -l&lt;/code&gt;. To quickly fingerprint all public keys a user has registered just run:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;n&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/joaomsa.keys&quot;&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read &lt;/span&gt;key&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;ssh-keygen &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; /dev/fd/0 &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$key&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Now in a more palatable format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2048 d6:0a:99:58:55:fd:bf:0b:d4:21:a2:0d:a2:44:c2:d4 /dev/fd/0 (RSA)
2048 e9:bd:b0:97:d5:3c:b5:d5:6f:fe:9d:aa:76:d3:42:0d /dev/fd/0 (RSA)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
    </item>
    

  </channel> 
</rss>
