<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Dmytro Kovalov: Personal projects, blog, tips and tricks, UNIX development, administration and devops.</title>
    <link>http://dmytro.github.com/</link>
    <atom:link href="http://dmytro.github.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>Ruby, Perl, Javascript development, UNIX system administration and monitoring. Open source projects developed for my satisfaction and for fun, most of these available either on Github or CPAN. For closed source software provided short description, and probably a couple of screen-shots. Please feel free to use, to re-distribute, to critic and to contribute.
</description>
    <language>en-us</language>
    <pubDate>Fri, 19 Jun 2015 15:00:57 +0900</pubDate>
    <lastBuildDate>Fri, 19 Jun 2015 15:00:57 +0900</lastBuildDate>

    
    <item>
      <title>iPhoto and files permission</title>
      <link>http://dmytro.github.com//2014/09/16/iphoto_and_files_permission..html</link>
      <pubDate>Tue, 16 Sep 2014 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2014/09/16/iphoto_and_files_permission.</guid>
      <description>&lt;p&gt;&lt;em&gt;Why is it so difficult to execute chown or chmod with root password?
 Migrating photo album from iPhoto 8 to iPhoto 9 does not seem and easy task on Mac anymore.
&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;First of all iPhoto refuses to upgrade any old library, if it resides on Netatalk volume. It just hangs indefinitely without seemingly doing anything. Then, after you copy all you library to local disk and start rebuilding/upgrading you&#39;d see following dialogs:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2014-09-16-iphoto_and_files_permission.iphoto1.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/2014-09-16-iphoto_and_files_permission.iphoto2.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;/images/2014-09-16-iphoto_and_files_permission.iphoto3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;But... I&#39;m sorry, iPhoto! I just gave you my root password!? What else do you need to repair permissions? Why simple &lt;code&gt;chmod -R 777&lt;/code&gt; works for me  and not for you?&lt;/p&gt;

&lt;p&gt;Worth mentioning that upgrades are not 100% safe, some libraries are partially broken after completion... :(&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Is MacOSX 10.9 == MacOS 9.x?</title>
      <link>http://dmytro.github.com//2013/12/20/is_macosx_10.9_macos_9.x..html</link>
      <pubDate>Fri, 20 Dec 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/12/20/is_macosx_10.9_macos_9.x.</guid>
      <description>&lt;p&gt;&lt;em&gt;My Mac is crashing... Again, after 10+ years of stability.
. I am mac user since MacOS 7.1. 7.x never crashed on  me, 8.x was kind of OK, 9.x sucked.
.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now after upgrading to Maverick I am rebooting more or less regularly to fix some of the problems. I never had any problems on any of the Macs with audio or with camera (on Macs with cameras). Currently I have already rebooted several times to fix missing sound, and my camera in Skype still does not work.&lt;/p&gt;

&lt;p&gt;As a UNIX SA I know for sure that nobody needs to reboot UNIX based computer for any reason but kernel upgrade. Not if you are Mac user anymore...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;/end_of_grunt&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Same sad story with iOS 7. It sucks seriously. Because of permanent crashing and all other bugs. This is the worst iOS version I&#39;ve used.&lt;/p&gt;

&lt;p&gt;Apple problems started last time when Steve Jobs was kicked out of Apple. Then he was back, Mac was back. Now, sadly, there&#39;s no way to get him again. Does it mean Apple is going down forever? Hope not so.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Running Chef roles from Capistrano</title>
      <link>http://dmytro.github.com//2013/12/04/running_chef_roles_from_capistrano.html</link>
      <pubDate>Wed, 04 Dec 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/12/04/running_chef_roles_from_capistrano</guid>
      <description>&lt;p&gt;&lt;em&gt;Chef databags are used to pass information between sessions of Capistrano and Chef.
 Databags are generated on Capistrano side and then used by Chef for server and components configuration.
&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my new project &lt;a href=&quot;/2013/11/01/chef_and_capistrano_integration.html&quot;&gt;&lt;em&gt;und Capiche&lt;/em&gt;&lt;/a&gt; I use tandem of Capistrano (or &lt;em&gt;cap&lt;/em&gt;) and Chef-solo (&lt;em&gt;chef&lt;/em&gt;) to deploy stacks of applications. Stacks are collections of server configuration, software packages required to run application, software configuration, and application code itself.&lt;/p&gt;

&lt;h1&gt;Capistrano + Chef&lt;/h1&gt;

&lt;p&gt;Here&#39;s a brief flow of typical deployment process in this schema:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;locally capistrano creates configuration to be used in Chef;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;cap&lt;/em&gt; copies Chef-solo and configuration to all remote hosts;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;cap&lt;/em&gt; starts chef-solo on remote hosts;&lt;/li&gt;
&lt;li&gt;after &lt;em&gt;chef&lt;/em&gt; finished, &lt;em&gt;cap&lt;/em&gt; starts standard application deployment.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Databag messenger&lt;/h2&gt;

&lt;p&gt;There are significant differences in how &lt;em&gt;cap&lt;/em&gt; and &lt;em&gt;chef&lt;/em&gt; executed. First and main difference is that they are invoked on different servers. &lt;em&gt;Cap&lt;/em&gt; starts deployment from local server, but &lt;em&gt;chef&lt;/em&gt; processes (possibly many of them) run on remote servers in parallel.&lt;/p&gt;

&lt;p&gt;There are no standard ways (like calling method and passing arguments) for information exchange between &lt;em&gt;cap&lt;/em&gt; and &lt;em&gt;chef&lt;/em&gt;. I use &lt;em&gt;chef databags&lt;/em&gt; as information medium between &lt;em&gt;cap&lt;/em&gt; and &lt;em&gt;chef&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Capistrano needs an ability to generate databags from its own configuration in the format that &lt;em&gt;chef&lt;/em&gt; cookbooks understand; also capistrano should be able to read and search &lt;em&gt;chef&lt;/em&gt; databags.&lt;/p&gt;

&lt;h3&gt;Hosts (AKA nodes) databag&lt;/h3&gt;

&lt;p&gt;First and very important task, is to be able to pass server configuration -- including roles -- from local Capistrano process to the remote nodes, where &lt;em&gt;chef&lt;/em&gt; can use it. Example below shows how this could be implemented.&lt;/p&gt;

&lt;p&gt;Suppose you have hosts configuration like the following:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.10&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:admin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mysql01&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.11&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;web01&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.12&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;web02&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.13&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:dns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:security&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:monitoring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no_release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;master&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;From this configuration Capistrano recipe creates databag called &lt;code&gt;:node&lt;/code&gt; with one item for each capistrano host. Example of a recipe:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:roles&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;find_servers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\./&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;role_names_for_host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;fqdn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;      &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:hostname&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;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;ss&quot;&gt;ipaddress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;ss&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;   &lt;span class=&quot;n&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;options&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;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Generated databag for one of the host looks like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;10_0_1_11&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;role&amp;quot;&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;logger&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;dns&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;security&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;monitoring&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;fqdn&amp;quot;&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;10.0.1.11&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;ipdaress&amp;quot;&lt;/span&gt;   &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;10.0.1.11&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
     &lt;span class=&quot;s2&quot;&gt;&amp;quot;options&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;s2&quot;&gt;&amp;quot;no_release&amp;quot;&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;s2&quot;&gt;&amp;quot;hostname&amp;quot;&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;master&amp;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;p&gt;This databag can be used directly with &lt;em&gt;chef&lt;/em&gt; recipes, using &lt;code&gt;data_bag_item&lt;/code&gt; or &lt;code&gt;search&lt;/code&gt; methods as for example:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;servers&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;monitoring&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;roles:*monitoring*&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: There is one trick though. Recipe needs to be written in such a way as to support search in &lt;em&gt;Chef-solo&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;By default &lt;em&gt;Chef-solo&lt;/em&gt; is only able to use data bags for &lt;code&gt;data_bag&lt;/code&gt; and &lt;code&gt;data_bag_item&lt;/code&gt; operations; to use search with solo you need to use extension &lt;a href=&quot;TODO&quot;&gt;chef-solo-search&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note 2&lt;/strong&gt;: In some cases this is not enough, however: if cookbook designed in such a way that search is explicitly prohibited in solo mode, some changes to the cookbook are necessary. Below is an example of the modifications I had to do for &lt;em&gt;Munin&lt;/em&gt; cookbook to make it work with both &lt;em&gt;Chef-solo&lt;/em&gt; and search.&lt;/p&gt;&lt;/blockquote&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;# Original cookbook recipe&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Chef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:solo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;sysadmins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_bag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;users&amp;#39;&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;map&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;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_bag_item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;users&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&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;c1&quot;&gt;# Change to&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;cant_search&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Chef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:solo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recipes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/chef-solo-search/&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;empty?&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cant_search&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;sysadmins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_bag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;users&amp;#39;&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;map&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;user&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_bag_item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;users&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&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;h2&gt;Applying Chef roles&lt;/h2&gt;

&lt;p&gt;There are two sides to actual executing a Chef cookbook via capistrano: &lt;em&gt;cap&lt;/em&gt; side and &lt;em&gt;chef&lt;/em&gt;. On every server we need to execute command that applies configuration specific to that server. We could do this sequentially, by using &lt;code&gt;:hosts&lt;/code&gt; option to &lt;code&gt;run&lt;/code&gt; method, but this will be really slow.&lt;/p&gt;

&lt;p&gt;Instead of this, I am using a bit of Capistrano magic and small Ruby script on remote server(s) side.&lt;/p&gt;

&lt;h3&gt;Capistrano task&lt;/h3&gt;

&lt;p&gt;Following task starts parallel run of remote script &lt;code&gt;run_roles.rb&lt;/code&gt; on all servers with option that contains server name from &lt;em&gt;cap&lt;/em&gt; configuration. This &lt;code&gt;$CAPISTRANO:HOST$&lt;/code&gt; variable is special Capistrano magic, it is internally converted by Capistrano to &lt;code&gt;server.host&lt;/code&gt; (Note: It is &lt;em&gt;not&lt;/em&gt; shell variable, it is set by Capistrano &lt;em&gt;before&lt;/em&gt; shell runs).&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:roles&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;try_sudo&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chef_solo_remote&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;/run_roles.rb  $CAPISTRANO:HOST$ }&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;On remote (i.e. &lt;em&gt;chef&lt;/em&gt; side) there&#39;s a small script, that takes &lt;code&gt;server.host&lt;/code&gt; as an argument and applies roles from &lt;code&gt;node&lt;/code&gt; databag.&lt;/p&gt;

&lt;p&gt;What happens here is the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;script reads databag with current server configuration;&lt;/li&gt;
&lt;li&gt;it reads all roles files (&lt;code&gt;role.json&lt;/code&gt;) that are listed in the databag;&lt;/li&gt;
&lt;li&gt;combines them into single &lt;code&gt;run_list&lt;/code&gt;; and&lt;/li&gt;
&lt;li&gt;runs &lt;em&gt;chef-solo&lt;/em&gt; using combined run list.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;ss&quot;&gt;Chef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:solo&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;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;Chef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:data_bag_path&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;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/data_bags&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;current_host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ARGV&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\./&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;_&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_host&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;roles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;Chef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:DataBagItem&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_host&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;s2&quot;&gt;&amp;quot;role&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;run_lists&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;n&quot;&gt;roles&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&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;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.json&amp;quot;&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;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;role&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;run_lists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;role&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;s2&quot;&gt;&amp;quot;run_list&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_host&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.json&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;w&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run_lists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;compact&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniq&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;to_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cd &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; chef-solo --config solo.rb --json-attributes &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current_host&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.json&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;PTY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;stdin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&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;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;Errno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:EIO&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;PTY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ChildExited&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;The child process exited!&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h1&gt;Next steps&lt;/h1&gt;

&lt;p&gt;To be able to deploy full stacks of applications additionally to basic hosts information Capistrano needs to share all its configuration with Chef. In next installments I will describe how this can be achieved.&lt;/p&gt;

&lt;!--  LocalWords:  und Capiche sysadmins sudo config PTY stdin pid
 --&gt;

</description>
    </item>
    
    <item>
      <title>und Capiche</title>
      <link>http://dmytro.github.com//2013/11/01/chef_and_capistrano_integration.html</link>
      <pubDate>Fri, 01 Nov 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/11/01/chef_and_capistrano_integration</guid>
      <description>&lt;h1&gt;What is it?&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Capistrano is primarily used as web application deployment framework. It is excellent combination of remote parallel execution of SSH commands with work-flow management. Chef, on the other side, is designed as configuration management tool and mostly used to configure infrastructure.
 Is it possible to combine powers of Capistrano and Chef for simpler and faster deployments, with simplified configuration? Can I deploy infra and application in a single step?
&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I&#39;ve made several attempts to combine powers of Chef and Capistrano: &lt;a href=&quot;https://github.com/dmytro/aws_deploy&quot;&gt;aws_deploy&lt;/a&gt;, &lt;a href=&quot;https://github.com/dmytro/chef-solo&quot;&gt;chef-solo&lt;/a&gt;, &lt;a href=&quot;https://github.com/dmytro/capistrano-recipes&quot;&gt;capistrano-recipes&lt;/a&gt;. This is a start for the new project.&lt;/p&gt;

&lt;h1&gt;Application Centric Architectures&lt;/h1&gt;

&lt;p&gt;In the old days deploying a server took longer. Rack it: optimistically - one day (if you&#39;re lucky, you could reuse somebody else&#39;s retired box); you (or your SA&#39;s) install OS on it - another day (with all the approvals and manual configs). In extreme cases (not a joke!) deploying a server took me 5 to 6 months.&lt;/p&gt;

&lt;p&gt;Application design was largely influenced or dictated by infrastructure architecture. Not only because of the price of the hardware, but also because of the difficulties with the deployment, multiple applications were sharing single server: &lt;em&gt;&quot;Our existing DB server has a lot of RAM and disks, we will put every possible database on it. When we run out, we will add disks and memory or migrate box to larger hardware or we build a cluster.&quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These days architecture of the infrastructure is rather influenced by the application environment. Each application can have distinct architecture, different from any other application or even dynamically changing architecture, depending on the needs. Since deploy of a new server can take less than a minute, they are created when required, and there is no need to share.&lt;/p&gt;

&lt;h2&gt;Management&lt;/h2&gt;

&lt;p&gt;Dynamics of the environment makes administration of the architecture easier and more difficult at the same time.&lt;/p&gt;

&lt;p&gt;Easier, because of the one function per server approach. We can decommission (or upgrade) server and be sure that it did not serve any additional tasks that we are not aware of. For exactly the same reason shorter life-time of the server(s) is better.&lt;/p&gt;

&lt;p&gt;On the other side, management is a bit more difficult, because of higher number of servers that you need to manage. But this is where devops tools can really help.&lt;/p&gt;

&lt;h1&gt;What is my goal for this project?&lt;/h1&gt;

&lt;p&gt;I want to build servers from scratch. If not from bare metal, then at least from &#39;bare OS installation&#39;. Not just servers, but &#39;architectures&#39; - tailored for applications. Servers organized into logical groups, with application functioning at the end of single step deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I want to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;have a list of hosts or IP&#39;s;&lt;/li&gt;
&lt;li&gt;an SSH key(s);&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Sudo&lt;/code&gt; or &lt;code&gt;su&lt;/code&gt; access;&lt;/li&gt;
&lt;li&gt;define server role(s), like &lt;code&gt;:app&lt;/code&gt; (Note: I am following Ruby and Capistrano conventions here), &lt;code&gt;:monitoring&lt;/code&gt;, &lt;code&gt;:logger&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;run deployment;&lt;/li&gt;
&lt;li&gt;have running application on newly deployed server(s) is XX minutes;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;I want to avoid:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This should be easy to configure for end user, avoid writing extensive configuration for each new application or &lt;em&gt;&#39;architecture&#39;&lt;/em&gt;: just hostnames and roles.&lt;/li&gt;
&lt;li&gt;Additionally, I want to be independent from any specifics of cloud or non-cloud provider.&lt;/li&gt;
&lt;li&gt;Similarly, I wish avoid building custom configuration and deployment management infrastructure (such as Chef or Puppet servers). My idea is to bring my laptop to you, plug it in (or let you git clone configuration repository), and by running single command have &lt;em&gt;your&lt;/em&gt; application deployed in minutes (or, let&#39;s say dozens of minutes).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Yes, there are drawbacks. Configuring lists of hostnames or IP addresses in files is not scalable in the long run -- for large-scale applications or for multiple applications, for hundreds of hosts. One step at a time...&lt;/p&gt;

&lt;h2&gt;Chef and Capistrano&lt;/h2&gt;

&lt;p&gt;I had made several approaches trying to make Cap and Chef work together.&lt;/p&gt;

&lt;p&gt;First attempt was a project called &lt;a href=&quot;...&quot;&gt;aws_deploy&lt;/a&gt;. Simply speaking it is a Ruby wrapper around AWS API, Chef-solo and Capistrano. Goal of the project was to have a single step deployment of application server in EC2 environment. AWS deploy is able to spawn new AWS instance if it does not exist, bootstrap it and install required git branch of RoR application.&lt;/p&gt;

&lt;p&gt;Although this project simplified deployment process a bit, shortcomings of the AWS Deploy design are obvious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Deploy is able to deploy only single instance at a time;&lt;/li&gt;
&lt;li&gt;chef-solo is not really configurable and only delivers standard static configuration server prepared to run Ruby on Rails;&lt;/li&gt;
&lt;li&gt;there is no interaction between Capistrano and Chef, they simply executed one after another by script wrapper.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;Cap + Chef = Capiche&lt;/h1&gt;

&lt;p&gt;Capistrano recipes often have some kind of installation task. Before deploying a configuration, you have to install the package. Such recipes are usually similar to the example below:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:nginx&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:install&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;apt-get install -y nginx&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There&#39;s an obvious problem with the recipe: it is not portable. This will work only on Debian or Ubuntu, and even on these systems there cases when this is not enough: what if I want different version of Nginx, or if I want to compile it from source with some custom configuration.&lt;/p&gt;

&lt;p&gt;At the same time Chef is designed to handle such situations, and have all necessary DSL for it.&lt;/p&gt;

&lt;p&gt;Is it possible to change Capistrano recipe like one above and make it use Chef cookbook instead?&lt;/p&gt;

&lt;p&gt;This is exactly what I am trying to achieve with the new project I am calling &lt;strong&gt;Unified Deployment with Capistrano and Chef&lt;/strong&gt; or &lt;em&gt;&#39;und Capiche&#39;&lt;/em&gt; (AKA &lt;em&gt;Capiche&lt;/em&gt;) for short.&lt;/p&gt;

&lt;p&gt;The new project is not really new, it&#39;s rather a combination of the efforts from previous similar projects. Some things is already implemented and working, as I write this. But functionality and code are spread across multiple repositories and it&#39;s not easy even for myself to join pieces together to design deployment for new project.&lt;/p&gt;

&lt;h2&gt;Components&lt;/h2&gt;

&lt;p&gt;Current &lt;em&gt;Capiche&lt;/em&gt; setup is based on RVM, Capistrano &lt;code&gt;2.x&lt;/code&gt;, Chef-solo and Capistrano &lt;a href=&quot;https://github.com/railsware/capistrano-multiconfig&quot;&gt;multi-configuration extension&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Current state&lt;/h2&gt;

&lt;p&gt;Below is an example of how configuration file for an application. This is actual working setup.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.10&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:admin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mysql01&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.11&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;web01&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.12&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;ss&quot;&gt;:app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:web&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;              &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;web02&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;server&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10.0.1.13&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:dns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:security&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:monitoring&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;no_release&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;master&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:app&lt;/code&gt;, &lt;code&gt;:web&lt;/code&gt; and &lt;code&gt;:db&lt;/code&gt; are standard Capistrano roles for Rails application,&lt;/li&gt;
&lt;li&gt;additional roles present here are &lt;code&gt;:admin&lt;/code&gt;, &lt;code&gt;:logger&lt;/code&gt;, &lt;code&gt;:security&lt;/code&gt;, and &lt;code&gt;:monitoring&lt;/code&gt; - new roles can be defined as necessary.&lt;/li&gt;
&lt;li&gt;Similarly &lt;code&gt;:primary&lt;/code&gt; and &lt;code&gt;:no_release&lt;/code&gt; are standard Capistrano host options, but&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:hostname&lt;/code&gt; is custom option used to set target host hostname and DNS.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Capistrano roles one-to-one correspond to roles on Chef side. This allows skip additional configuration.&lt;/p&gt;

&lt;p&gt;Each Chef JSON role is simply a pointer to a more details role Ruby file. JSON roles look similar to:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;javascript&quot;&gt;&lt;span class=&quot;c1&quot;&gt;// app.json&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;run_list&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;role[rails_common]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;role[common]&amp;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;span class=&quot;c1&quot;&gt;// logger.json&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;run_list&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;role[logger]&amp;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;span class=&quot;c1&quot;&gt;// mysql.json&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;run_list&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;role[mysql]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;role[common]&amp;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;span class=&quot;c1&quot;&gt;// web.json&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;run_list&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;role[web]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;role[common]&amp;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;p&gt;Example of Ruby role file:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;common&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Components required on every node&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;run_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[user::databag]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[deep_security]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[rsyslog]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[chef-solo-search]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[yum::epel]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[yum::remi]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;role[monitoring_client]&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;recipe[git]&amp;quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;default_attributes&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;user&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;ss&quot;&gt;:data_bag_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:users&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Scope&lt;/h2&gt;

&lt;p&gt;It is important to understand, that main target of this kind of setup is small to medium sort of applications -- tens of servers, rather than hundreds or thousands. But, at the same time, there are thousands of such applications, therefore ease of configuration and adaptability to the environment of next application is a key.&lt;/p&gt;

&lt;h2&gt;Project home&lt;/h2&gt;

&lt;p&gt;There is no code now in Github repo, as I write this, I only created new repo few minutes ago, but I am starting moving bits and pieces from other places. Watch &lt;a href=&quot;https://github.com/dmytro/und_capiche&quot;&gt;this space&lt;/a&gt;.&lt;/p&gt;

&lt;!--  LocalWords:  und Capiche SA Centric decommission devops SA&#39;s configs db admin mysql dns rsyslog repo
 --&gt;



</description>
    </item>
    
    <item>
      <title>Speeding up Jekyll site</title>
      <link>http://dmytro.github.com//2013/10/29/optimizing_jekyll.html</link>
      <pubDate>Tue, 29 Oct 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/10/29/optimizing_jekyll</guid>
      <description>&lt;p&gt;&lt;em&gt;Recently I&#39;ve added some optimizations to my Jekyll setup for faster page loading.
 Google and other search engines consider page load speed when building their ratings. It means that improving load speed can boost your SEO rating too, not only your users happiness.
&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;Understanding the problem&lt;/h1&gt;

&lt;p&gt;Most of the optimizations in my case was about shrinking CSS, Javascript and images, removing blank spaces from HTML and reducing number of HTTP request by joining assets into single asset file.&lt;/p&gt;

&lt;p&gt;But before doing optimization it is better to understand where do you stand and what do you want to optimize.&lt;/p&gt;

&lt;p&gt;Good page speed analyzer can be help with the task, I&#39;ve found decent one at &lt;a href=&quot;http://gtmetrix.com/&quot;&gt;http://gtmetrix.com/&lt;/a&gt;. There are others as well, for example &lt;a href=&quot;https://www.site24x7.com/web-page-analyzer.html&quot;&gt;https://www.site24x7.com/web-page-analyzer.html&lt;/a&gt;, Google has some too.&lt;/p&gt;

&lt;p&gt;GTMetrics analyzer is pretty good, it grades the page by relative standing of your page to average page stats on the net, and can grade importance of each metric and recommendations for speed improvements. is Whatever comes red on their report is probably worth your attention.&lt;/p&gt;

&lt;p&gt;In my case the most critical things where decreasing number of HTTP request for CSS and Javascript files and reducing size of the hosted images.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1&gt;Assets pipeline&lt;/h1&gt;

&lt;h2&gt;Javascript and CSS handling&lt;/h2&gt;

&lt;p&gt;I was quite pleased to find for the assets handling &lt;code&gt;jekyll-assets&lt;/code&gt; gem that works with Jekyll out of the box, and it handles assets very similar to the way Rails does it, so less learning for me. There are other solutions as well, obviously I haven&#39;t tested all of them, but among tested ones this one is on of the better ones.&lt;/p&gt;

&lt;p&gt;Adding the gem to Jekyll setup is quite simple, just include lines into &lt;code&gt;Gemfile&lt;/code&gt; and &lt;code&gt;_plugins/ext.rb&lt;/code&gt; accordingly:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;jekyll-assets&amp;#39;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;jekyll-assets&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Next step is a bit of reorganizing of how Javascript and CSS (or SASS) files are laid out in your working directory.&lt;/p&gt;

&lt;p&gt;In my setup JS and SASS files are in &lt;code&gt;./js/&lt;/code&gt; and &lt;code&gt;./sass/&lt;/code&gt; directories. Sass saves generated CSS&#39;s in &lt;code&gt;./css&lt;/code&gt;. For generating CSS files during local testing and when publishing I had sass command in my Rake task &amp;mdash; in more details this was described in &lt;a href=&quot;/2013/08/13/more_about_jekyll.html&quot;&gt;previous post&lt;/a&gt; &amp;mdash; but with introducing assets pipeline this became redundant.&lt;/p&gt;

&lt;p&gt;Examples of the new Rake tasks are given below.&lt;/p&gt;

&lt;h3&gt;Refactoring assets&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Jekyll-assets&lt;/code&gt; introduces new directory &lt;code&gt;_assets&lt;/code&gt; with subdirectories &lt;code&gt;stylesheets&lt;/code&gt; and &lt;code&gt;javascripts&lt;/code&gt;. I&#39;ve moved all my .js and .sass files to the new location and replaced all &lt;code&gt;style&lt;/code&gt; and &lt;code&gt;script&lt;/code&gt; references from the code with just 2 lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{% javascript app %}
{% stylesheet app %}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Jekyll-assets&lt;/code&gt; uses similar to Rails assets declaration, so to include all of my JS and CSS, what I had to do is to create two new files &amp;mdash; one in each directory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File &lt;code&gt;_assets/stylesheets/app.css&lt;/code&gt;

&lt;pre&gt;&lt;code&gt;  #= require cssnormalize-min
  #= require dmytro
  #= require pygments
  #= require fancybox
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;File &lt;code&gt;_assets/javascripts/app.js&lt;/code&gt;

&lt;pre&gt;&lt;code&gt;  #= require jquery
  #= require jquery.tagcloud
  #= require fancybox
  #= require tag_cloud
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Resulting parsed JS and CSS tags look like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/assets/app-e4c2b9c81e41368c0fcc779280bd5530.css&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;/assets/app-b80c4942bb62b4e63380a8693c39923c.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Optimizing images&lt;/h2&gt;

&lt;p&gt;Another important aspect of optimization is reducing file size of the images. There are two parts in it: reducing geometry of the (mainly) photos, and second is adding some optimization to reduce file of the image. Both JPEG&#39;s and PNG&#39;s can be reduced quite significantly.&lt;/p&gt;

&lt;h3&gt;Reduce geometry of JPEG files&lt;/h3&gt;

&lt;p&gt;First of all, files exported from iPhoto or such, can end up in a lot of various sizes. Sometimes you just forget to select proper reduction and have image files of impractical for the web sizes. ImageMagick can handle this quite easy, only needed is to add simple Rake task for it.&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;resize&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%{mogrify -resize &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAX_GEOMETRY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:w&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;MAX_GEOMETRY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;#39;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    
    &lt;span class=&quot;no&quot;&gt;MAX_GEOMETRY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1280&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;960&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:jpeg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    
        &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
          &lt;span class=&quot;vi&quot;&gt;@jpgs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;**/*.jpg&amp;quot;&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;no&quot;&gt;Dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;_site/**/*.jpg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    
        &lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Scale down images to max geometry allowed&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:resize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
          &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&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;vi&quot;&gt;@jpgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jpg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popen&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;identify &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jpg&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;
              &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bla&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/ /&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sub!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/jpg\[\d+\]$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;jpg&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&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;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:to_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MAX_GEOMETRY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:w&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;n&quot;&gt;h&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;MAX_GEOMETRY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;h3&gt;Optimize JPEG&#39;s and PNG&#39;s&lt;/h3&gt;

&lt;p&gt;Additionally to geometry reduction significant size reduction can be gained by optimizing imgages: removing unnecessary Exif tags and comments from JPEG&#39;s or applying various deflating algorithms. For PNG&#39;s optimizations are lossless, but for JPEG&#39;s you can select to reduce image quality or do lossless optimization.&lt;/p&gt;

&lt;p&gt;Binaries for image optimizations are available for both MacOSX and Linux. On MacOSX &lt;code&gt;jpegoptim&lt;/code&gt; is available as part of Homebrew and is installed simply by &lt;code&gt;brew install jpegoptim&lt;/code&gt;. As for the PNG optimization &lt;code&gt;pngout&lt;/code&gt; binary is downladable from &lt;a href=&quot;http://www.jonof.id.au/kenutils&quot;&gt;Ken Silverman&#39;s Utilities page&lt;/a&gt;.&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Compress JPEG images&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:minimize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
      &lt;span class=&quot;vi&quot;&gt;@jpgs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;jpegoptim --strip-all --totals -o &amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;#39;&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:png&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;taks&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;omitted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Compress PNG images&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:minimize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:list&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
  &lt;span class=&quot;vi&quot;&gt;@pngs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;png&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;./bin/pngout &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; -q | true&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; : &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;png&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; bytes smaller &amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;hr /&gt;

&lt;h1&gt;HTML compression&lt;/h1&gt;

&lt;p&gt;For further reduction of the web page(s) size stripping all excessive white spaces and html comments can help too. There&#39;s a Jekyll plug-in (more than one) for that too. I&#39;ve tried couple of them and stopped on &lt;code&gt;jekyll-minify-html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is also installable as gem. To start using in, just add &lt;code&gt;require &#39;jekyll-minify-html&#39;&lt;/code&gt; statement in &lt;code&gt;_plugins/ext.rb&lt;/code&gt; and &lt;code&gt;env: production&lt;/code&gt; in &lt;code&gt;_config.yml&lt;/code&gt;. That&#39;s it.&lt;/p&gt;

&lt;p&gt;However I find it quite heave and usually comment out when previewing page locally. That&#39;s brings another topic of Jekyll slowness, see below.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1&gt;Rake tasks&lt;/h1&gt;

&lt;p&gt;Finally, these are new Rake tasks for publishing site to Github and for building it locally for preview.&lt;/p&gt;

&lt;h3&gt;Rake run&lt;/h3&gt;

&lt;p&gt;This task starts locally Jekyll for previewing site on the local machine.&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;compile and run the site locally&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:run&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;pids&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;n&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;jekyll serve --watch --drafts&amp;quot;&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;nb&quot;&gt;trap&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INT&amp;quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;INT&amp;quot;&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;pids&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
 
  &lt;span class=&quot;kp&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sleep&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;h3&gt;Rake publish&lt;/h3&gt;

&lt;p&gt;Build site and publish it to Github. In this task I also use &lt;code&gt;jpegoptim&lt;/code&gt; to optimize all thumb-nails from &lt;a href=&quot;https://github.com/redwallhp/JekyllGalleryTag&quot;&gt;Jekyll GalleryTag plugin&lt;/a&gt; which are generated automatically on page build (on line 6).&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;1
2
3
4
5
6
7
8&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;desc&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;compile and publish the site to Github&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:publish&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;git checkout source&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%x{ git log -n 1 --no-merges --format=%s%b }&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chomp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;jekyll build&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;jpegoptim --strip-all --totals -o _site/images/galleries/*-thumb*&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cd _site &amp;amp;&amp;amp; git add -A &amp;amp;&amp;amp; git commit -m &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Publishing at $(date): &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;comment&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; git push origin master&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;hr /&gt;

&lt;h1&gt;Some stats ...&lt;/h1&gt;

&lt;p&gt;Just some stats about size reduction as result of these experiments. There numbers are far from being precise. During all these changes I kept adding posts and images to the site, so it&#39;s hard to tell exactly how much space each one have saved. I only can roll back my git repo and see how size changed between commits.&lt;/p&gt;

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;th&gt;Before &lt;th&gt; After
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Full page generated size (kB&#39;s)&lt;/em&gt;
    &lt;td&gt; 483,524
    &lt;td&gt; 478,324
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Number of image files&lt;/em&gt;
    &lt;td&gt; 375
    &lt;td&gt; 878
&lt;tr&gt;&lt;td&gt;&lt;em&gt;Assets size (kB&#39;s)&lt;/em&gt;
    &lt;td&gt; 88(css) + 184(js)
    &lt;td&gt; 188 &lt;em class=&#39;smaller&#39;&gt;(JS+CSS together, including GZ&#39;ipped copies)&lt;/em&gt;
&lt;tr&gt;&lt;td&gt;&lt;em&gt;GTmetrix Y Slow grade&lt;/em&gt;
    &lt;td&gt; C
    &lt;td&gt; B
&lt;/table&gt;


&lt;p&gt;Even with number of photos (main size factor on this site) increase about twice overall size went a bit down, and as for JS and CSS total size reduced by about 40%, not mentioning that instead of about dozen HTTP requests there are only 2 now.&lt;/p&gt;

&lt;h1&gt;... and problems&lt;/h1&gt;

&lt;h2&gt;Jekyll is slow&lt;/h2&gt;

&lt;p&gt;After I started playing with multiple Jekyll plugins, I&#39;ve started noticing significant slowing of the page generation. Even for small page changes it takes multiple tens of seconds to recreate file and page reload often show missing file or not regenerated CSS&#39;s.&lt;/p&gt;

&lt;p&gt;Full page build with CSS/JSS/HTML compression tames more than 2 minutes, and this is only for 48 blog posts (this one is 49&#39;s).&lt;/p&gt;

&lt;h2&gt;Liquid is quite limiting&lt;/h2&gt;

&lt;p&gt;Another problem is that Liquid templating used by Jekyll is, while easy to learn one, is quite limited and a bit hard to extend.&lt;/p&gt;

&lt;p&gt;I am finding that doing even simple (not-supported) things in Liquid is virtually impossible without writing custom plugin. Things, that in ERB would be done with 2-3 ruby commands, requires a lot of jumping through the loops.&lt;/p&gt;

&lt;h3&gt;Middleman?&lt;/h3&gt;

&lt;p&gt;Time to look for something new?&lt;/p&gt;

&lt;p&gt;Recently I&#39;ve read some intros to &lt;a href=&quot;http://middlemanapp.com/&quot;&gt;Middleman&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So far my impressions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ERB vs Liquid is &lt;em&gt;GOOD THING&lt;/em&gt;. &lt;em&gt;I can compare this relationship to that one of Puppet vs Chef, i.e. custom configuration language plus some added on top of it Ruby DSL vs clean from the start DSL&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;things, that require a lot of plumbing in Jekyll are by default in Middleman (one example, being &lt;a href=&quot;http://middlemanapp.com/asset-pipeline/&quot;&gt;Asset Pipeline&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Oh well...&lt;/p&gt;

&lt;!--  LocalWords:  SEO GTMetrics mdash stylesheets javascripts javascript app stylesheet endraw cssnormalize min pygments fancybox jquery tagcloud html JPEG&#39;s linenos Exif jpegoptim Homebrew pngout downladable Silverman&#39;s GalleryTag plugin ERB
 --&gt;

</description>
    </item>
    
    <item>
      <title>More experience with Jekyll and setup changes</title>
      <link>http://dmytro.github.com//2013/08/13/more_about_jekyll.html</link>
      <pubDate>Tue, 13 Aug 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/08/13/more_about_jekyll</guid>
      <description>&lt;p class=&quot;italic&quot;&gt; New features added to the Jekyll gem, at the same time trying to extend my Jekyll setup I hit Github limitations.
 Several times I&#39;ve tried to introduce plugins to Jekyll setup or some advanced feature, only to discover that Github disables some of the (quite useful) features.
. &lt;/p&gt;


&lt;h1&gt;Github&#39;s Jekyll&lt;/h1&gt;

&lt;h2&gt;Plugins&lt;/h2&gt;

&lt;p&gt;Use of plugins is disabled by Github for security reasons. End of story. You can&#39;t use Jekyll plugins when relying on generating your site by Github.&lt;/p&gt;

&lt;h2&gt;Related posts and LSI&lt;/h2&gt;

&lt;p&gt;It was troubling me for some time, since I didn&#39;t understand how exactly &lt;code&gt;post.related_posts&lt;/code&gt; function worked in Jekyll. In the related posts I always saw just a list of latest posts.&lt;/p&gt;

&lt;p&gt;After some searching and reading, I found that Jekyll has attribute &lt;code&gt;LSI&lt;/code&gt; to control how the list of related posts is generated. When LSI is &lt;code&gt;false&lt;/code&gt; result is simple list of latest posts, which I had. Also I discovered that Github disables LSI since it produces too much load on their resources.&lt;/p&gt;

&lt;p&gt;Solution is to run jekyll locally, generate site and push it to Github. The only thing I didn&#39;t know how to make it clean and not requiring lot of maintenance.&lt;/p&gt;

&lt;p&gt;Somebody had &lt;a href=&quot;http://www.trottercashion.com/2011/04/11/use-git-plumbing-for-more-awesome-github-pages.html&quot;&gt;this solution published&lt;/a&gt;, but problem with it was that on each publishing it is pushing whole site instead of changed files only. This is taking too long with my site, since I have some photos, PDF&#39;s and what not.&lt;/p&gt;

&lt;p&gt;Creating git repository in &lt;code&gt;_site&lt;/code&gt; directory didn&#39;t work because running jekyll build was also destroying &lt;code&gt;.git&lt;/code&gt; in it.&lt;/p&gt;

&lt;p&gt;Advises on &lt;a href=&quot;http://stackoverflow.com/questions/7555837/publish-jekyll-generated-to-gh-pages-and-not-overwite-the-git-in-site&quot;&gt;keeping .git with Jekyll&lt;/a&gt; gave me some ideas about going forward.&lt;/p&gt;

&lt;h1&gt;Jekyll v. 1.x&lt;/h1&gt;

&lt;p&gt;First of all, there&#39;s a lot of changes in Jekyll. I was running v.0.12.x and many changes happened since Jekyll moved to v.1.x, one important change is added option to keep some files from overwriting.&lt;/p&gt;

&lt;p&gt;Below is step by step process for publishing site with Jekyll running locally.&lt;/p&gt;

&lt;h2&gt;Process&lt;/h2&gt;

&lt;p&gt;You&#39;d need some changes to  the configuration of Jekyll.&lt;/p&gt;

&lt;h3&gt;Files&lt;/h3&gt;

&lt;p&gt;Configuration for included or excluded files for Jekyll generation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;File lists in Jekyll changed from simple list of space separated strings to arrays of strings. So, for example exclude list now looks differently (see below).&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;keep_files&lt;/code&gt; your &lt;code&gt;_config.yml&lt;/code&gt; file. It will preserve your &lt;code&gt;_site/.git&lt;/code&gt; repository information. This is, BTW default setting.&lt;/li&gt;
&lt;li&gt;Make sure to include &lt;code&gt;lsi&lt;/code&gt; attribute, so that your local Jekyll will use it for related content generation.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;&lt;span class=&quot;l-Scalar-Plain&quot;&gt;keep_files&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p-Indicator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;.git&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;exclude&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p-Indicator&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;bin&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Rakefile&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Guardfile&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;_posts/template.md.erb&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Gemfile*&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;template.md.erb&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;sass&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;presentations/css/theme/template&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;l-Scalar-Plain&quot;&gt;lsi&lt;/span&gt;&lt;span class=&quot;p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l-Scalar-Plain&quot;&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Setup git branches&lt;/h3&gt;

&lt;p&gt;Publications pushed to Github pages depend on the type of Github page. Here I am discussing &quot;user pages&quot;.&lt;/p&gt;

&lt;p&gt;User pages use master branch of the git repository. If master branch contains Markdown, Textile or other markup files Github&#39;s Jekyll will try to generate _site from it, but it won&#39;t try to generate anything if it&#39;s only HTML files.&lt;/p&gt;

&lt;p&gt;We&#39;d need to prepare branches accordingly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generated content should go into &lt;code&gt;master&lt;/code&gt; branch;&lt;/li&gt;
&lt;li&gt;all sources go into different branch. I&#39;ve chosen to call it &lt;code&gt;source&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Create source branch from current master&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
git checkout -b &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; 
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# And push it to source branch at Github&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
git push origin &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; -u
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Now, *before* pushing to remote master, clone it into _site directory.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
git clone -b master git@github.com:dmytro/dmytro.github.com.git _site
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;h3&gt;Add publishing task&lt;/h3&gt;

&lt;p&gt;Include this code into your Rakefile. You&#39;d need to change/add some shell commands accordingly.&lt;/p&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:publish&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Just make sure we are generating from source branch&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;git checkout source&amp;quot;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# I am using SASS for my CSS generation. You&amp;#39;d probably need to change this.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;scss sass/dmytro.sass:css/dmytro.css sass/style.sass:css/style.css&amp;quot;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;jekyll build&amp;quot;&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;# &lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sh&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cd _site &amp;amp;&amp;amp; git add -A &amp;amp;&amp;amp; git commit -m &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Publishing at $(date)&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; git push origin master&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;




&lt;!--  LocalWords:  jekyll plugins Github&#39;s LSI PDF&#39;s Gemfile endhighlight CSS
 --&gt;




&lt;!--  LocalWords:  scss cd
 --&gt;

</description>
    </item>
    
    <item>
      <title>Build new hosts with Capistrano and Chef</title>
      <link>http://dmytro.github.com//2013/05/21/easy_spawn_new_hosts_with_capistrano.html</link>
      <pubDate>Tue, 21 May 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/05/21/easy_spawn_new_hosts_with_capistrano</guid>
      <description>&lt;p&gt;&lt;em&gt;Include Chef recipes into Capistrano deploy script, and create full-blown application servers from scratch in a minutes
. &lt;p&gt; I was using Chef-solo to configure new hosts before they can be used to deploy applications by Capistrano. But Capistrano is not just for the app deployment!
.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;Call Chef from Capistrano&lt;/h1&gt;

&lt;p&gt;Capistrano is capable of executing batches of commands in parallel on multiple remote servers, and its only dependency is SSH access.  So, why not use this to spawn chef-solo processes on these servers?&lt;/p&gt;

&lt;p&gt;So, easy solution is to simply include your Chef-solo repository/scripts as a first step in the Capistrano deployment process. This way each time you do a deployment Chef will take care about configuring your server first. And if your server is not configured, or even just recently built, all necessary components will be magically deployed with simply typing &lt;code&gt;cap deploy&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Capistrano Recipe&lt;/h2&gt;

&lt;p&gt;Add this simple recipe to capistrano to make sure that Chef solo is started before any other Capistrano tasks:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;set_default&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:chef_solo_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expand_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;../chef-solo/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;set_default&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:chef_solo_json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;empty.json&amp;quot;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:chefsolo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; 
  &lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:deploy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%x{ mktemp /tmp/captemp-tar.XXXX }&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chomp&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;run_locally&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;cd &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chef_solo_path&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; tar cfz &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; . &amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;upload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:via&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:scp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;run_locally&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;rm -f &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;mkdir -p ~/chef &amp;amp;&amp;amp; cd ~/chef &amp;amp;&amp;amp; tar xfz &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &amp;amp;&amp;amp; rm -f &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;    
    &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;try_sudo&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; cd ~/chef &amp;amp;&amp;amp; bash ./install.sh &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chef_solo_json&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;before&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;deploy&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;chefsolo:deploy&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Just make sure that your &lt;code&gt;chef-solo&lt;/code&gt; repository is installed in the &lt;code&gt;./deploy/chef-solo&lt;/code&gt; directory or set &lt;code&gt;:chef_solo_path&lt;/code&gt; attribute accordingly.&lt;/p&gt;

&lt;p&gt;Full text of Chef-solo Capistrano recipe is available in &lt;a href=&quot;https://github.com/dmytro/capistrano-recipes&quot;&gt;the repository&lt;/a&gt; in &lt;code&gt;chef_solo.rb&lt;/code&gt; file.&lt;/p&gt;

&lt;h1&gt;Chef-solo Repository&lt;/h1&gt;

&lt;p&gt;This is &lt;a href=&quot;https://github.com/dmytro/chef-solo&quot;&gt;Chef-solo repository&lt;/a&gt; that I am using for my deployments. I forked it from somebody else, but heavily modified to suit my needs. Currently install script supports deployment/bootstrapping to MacOSX and several Linux distros. Among supported Linuxes are Debian/Ubuntu and RedHat/CentOS. Wan not tested with Fedora (maybe needs some adjustments for the Rpmforge).&lt;/p&gt;

&lt;h2&gt;Server Bootsrapping&lt;/h2&gt;

&lt;p&gt;Even if you do not need to install any additional software using Chef-solo, you still need to put some prerequisits on the server. Like Ruby for Rails development - is an abvious example.&lt;/p&gt;

&lt;p&gt;Chef-solo install script can do just that. Without any cookbooks, it would simply create development or production environment by installing: prerequisite development environment (development RPM&#39;s or DEB&#39;s), Ruby version manager - RVM, Ruby itself and Chef (in that order).&lt;/p&gt;

&lt;p&gt;For this simply set &lt;code&gt;:chef_solo_json&lt;/code&gt; attribute to &lt;code&gt;&quot;empty.json&quot;&lt;/code&gt; as in the example above. &lt;code&gt;&quot;empty.json&quot;&lt;/code&gt; is exactly what it says it&#39;s an JSON file that does not contain any recipes.&lt;/p&gt;

&lt;!--  LocalWords:  capistrano dirname chefsolo mktemp cd cfz scp mkdir xfz
 --&gt;


&lt;!--  LocalWords:  endhighlight
 --&gt;

</description>
    </item>
    
    <item>
      <title>More about custom CSS for RT4</title>
      <link>http://dmytro.github.com//2013/05/15/custom_css_for_rt4.html</link>
      <pubDate>Wed, 15 May 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/05/15/custom_css_for_rt4</guid>
      <description>&lt;p&gt;&lt;em&gt;How do I add custom CSS to RT, where is it?
. I&#39;ve received a question to my previous blog - &lt;a href=&quot;/2012/07/18/rt-custom-css.html&quot;&gt;RT can be less ugly&lt;/a&gt;. Question basically was, OK I have CSS, now where do I add it?
.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yes, it&#39;s not that easy to find this in RT interface. So, here is a small screen shot that shows how to get to this setting. Just don&#39;t forget you need to be logged in as root or as user who has permission to see this configuration menu.&lt;/p&gt;

&lt;p&gt;Select menu: &lt;em&gt;Tools &amp;raquo; Configuration &amp;raquo; Tools (again) &amp;raquo; Theme&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you&#39;re there, you&#39;ll find &lt;em&gt;Custom CSS (Advanced)&lt;/em&gt; text box, where you need to add your custom stuff:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013_05_15_custom_css_for_rt4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;From the same place you can customize some other visuals of the RT, like colors and company logo.&lt;/p&gt;

&lt;p&gt;Here&#39;s scren shot for colors and fonts GUI confiruation:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2013_05_15_custom_css_for_rt4_2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ruby 2 test drive</title>
      <link>http://dmytro.github.com//2013/03/18/ruby_2_test_drive.html</link>
      <pubDate>Mon, 18 Mar 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/03/18/ruby_2_test_drive</guid>
      <description>&lt;p&gt;&lt;em&gt;Ruby 2 is fast!
. First experience of running some of my scripts in Ruby 2 was: WOW !!!
.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ruby 2.0.0-p0 is barely out. I was wating for it to appear on RVM radar and today tried it finally. And ... as I said WOW !!!&lt;/p&gt;

&lt;p&gt;Look at the numbers below. It&#39;s not what you can call a scientific approach for benchmarking, but demonstrates main idea well enough.&lt;/p&gt;

&lt;p&gt;Running same small script in 2 Ruby revisions. Ususally second run is faster since some libraries are already preloaded in memory.&lt;/p&gt;

&lt;p&gt;Can you see the difference?&lt;/p&gt;

&lt;h2&gt;ruby-1.9.3-p374&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;  Run          First       Second 
               ------      -----
  real         2.12        1.68
  user         1.54        1.53
  sys          0.16        0.13
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;ruby-2.0.0-p0&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;  Run          First       Second 
               ------      -----
  real         0.89        0.66
  user         0.59        0.56
  sys          0.10        0.09
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
    <item>
      <title>Nagira v0.2.5 release</title>
      <link>http://dmytro.github.com//2013/03/15/nagira_v0.2.5_release.html</link>
      <pubDate>Fri, 15 Mar 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/03/15/nagira_v0.2.5_release</guid>
      <description>&lt;p&gt;&lt;em&gt;New release of Nagira RESTful API includes number of important features. Nagira version 0.2.5 is pretty big release, including number of significant changes.&lt;/p&gt;

&lt;p&gt;So I decided to jump version a little from 0.2.1 to 0.2.5&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And here is all the new wonderful features included in the release:&lt;/p&gt;

&lt;h2&gt;Background parser&lt;/h2&gt;

&lt;p&gt;Which speeds up all HTTP requests by parsing of the Nagios status file in separate thread.&lt;/p&gt;

&lt;p&gt;If you have a very big Nagios environment, parsing of status.dat file can take up to few seconds. Even though Nagira had a timed-parse feature before -- Nagira kept parsed data in a cache, and was not attempting to parse status more often than once in N seconds, once in a while unlicky user would have to wait for status update for several seconds.&lt;/p&gt;

&lt;p&gt;This is eliminated now by parser running in the background and doing its job in separate thread. Meaning that answer to all user queries are fast. This, of course, can put some extra load on the server, since it will need to do the parsing regardless of whether ther are any requests coming, so you need to tune your configuration depending on Nagios environment.&lt;/p&gt;

&lt;h2&gt;Partial ActiveSupport&lt;/h2&gt;

&lt;p&gt;Meaning that you can use Nagira now directly from Ruby on Rails application.&lt;/p&gt;

&lt;p&gt;ActiveSupport is indeed partial, more to come. Only pluralized nouns of the resources are supported now. What that means is that you can have your model defined like the following and get all your services information by &lt;code&gt;Service.all&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Service&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;ActiveResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:Base&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://localhost:4567/_status/&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;element_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;service&amp;quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Only &lt;code&gt;#all&lt;/code&gt; is supported at the moment (or &lt;code&gt;#find(:all)&lt;/code&gt;, which is the same).&lt;/p&gt;

&lt;h2&gt;Flexible configuration&lt;/h2&gt;

&lt;p&gt;More run time configuration options and environment varaibles available.&lt;/p&gt;

&lt;p&gt;It easier now to control how Nagira is run using shell environment variables instead of going to source code. This makes it easier to use for non Ruby users, as well as simplifies some of the start-up scripts and configurations, since now they are plain files and not ERB templates as it was in the previos releases.&lt;/p&gt;

&lt;p&gt;Additionally more configuration options are available in Nagira with thid release.&lt;/p&gt;

&lt;p&gt;For the full description of configuration see Nagira documentation and comments in Nagira defaults file. But here&#39;s list of configuration options available: port, bind address, UNIX user to run Nagira, RVM setting, TTL for data, enable or disable background parser, log file and Nagios main configuration file locations.&lt;/p&gt;

&lt;h2&gt;Nagira is gem now&lt;/h2&gt;

&lt;p&gt;Finally the most important feature of this release is that Nagira is now a Ruby gem. It is available for the standard &lt;a href=&quot;http://rubygems.org/gems/nagira&quot;&gt;RubyGems&lt;/a&gt; location. It can be downloaded from the site or installed using standard gem way or included into &lt;code&gt;Gemfile&lt;/code&gt; of the Ruby or Ruby on Rails project:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;gem install nagira
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Nagira relies on &lt;a href=&quot;https://github.com/ripienaar/ruby-nagios&quot;&gt;&lt;code&gt;ruby-nagios&lt;/code&gt;&lt;/a&gt; library for parsing Nagios files.  There was a big chunk of custom development, that I did for the &lt;code&gt;ruby-nagios&lt;/code&gt;. Finally all custom development submitted to upstream project, merged in and I can use &lt;code&gt;ruby-nagios&lt;/code&gt; gem instead of relying on my custom git branch. This made easier to refactor Nagira and convert it into gem.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>It's UNIX my dear Watson</title>
      <link>http://dmytro.github.com//2013/03/13/its_unix_my_dear_watson.html</link>
      <pubDate>Wed, 13 Mar 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/03/13/its_unix_my_dear_watson</guid>
      <description>&lt;p&gt;&lt;img src=&quot;/images/2013_03_13_it_s_unix_my_dear_watson.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;blockquote&gt;&lt;p&gt;Summary:
&lt;em&gt;Shell script for detecting aspects of UNIX OS: version, Linux distribution, clone name, release
.&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;

&lt;p&gt;In many shell scripts one can find pieces of code such as:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; grep -i centos /etc/redhat-release &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;   &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;DISTRO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CentOS
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
   ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and so on.&lt;/p&gt;

&lt;p&gt;It&#39;s not difficult task to find what OS/ditsro you are running on, but sometimes it takes couple minutes to remember what is actually different between Debian and Ubuntu to make reliable guess. And it is a repeating task, meaning that couple minutes can be spent more than once.&lt;/p&gt;

&lt;h1&gt;Meet Sherlock OS&lt;/h1&gt;

&lt;p&gt;This is a simple shell script to detect UNIX/Linux OS and various aspects of the OS. Especially for Linux: distribution type and derivative (such as CentOS/RHEL or Debian/Ubuntu)&lt;/p&gt;

&lt;p&gt;But it is packaged as real Ruby gem (I am mostly developing in Ruby these days), so installation is as simple as &lt;code&gt;gem install sherlock_os&lt;/code&gt;. After you install it you can do it like:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;sherlock
&lt;span class=&quot;nv&quot;&gt;OS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Linux
&lt;span class=&quot;nv&quot;&gt;MACH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;x86_64
&lt;span class=&quot;nv&quot;&gt;KERNEL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2.6.32-5-amd64
&lt;span class=&quot;nv&quot;&gt;DISTRIBUTION&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;debian
&lt;span class=&quot;nv&quot;&gt;FAMILY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;debian
&lt;span class=&quot;nv&quot;&gt;DERIVATIVE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Debian
&lt;span class=&quot;nv&quot;&gt;RELEASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;6.0.6
&lt;span class=&quot;nv&quot;&gt;CODENAME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;squeeze
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;or even&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt; &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;sherlock | grep DERIVATIVE&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;DERIVATIVE
Debian
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Documentation&lt;/h2&gt;

&lt;p&gt;Available at &lt;a href=&quot;http://dmytro.github.com/sherlock_os&quot;&gt;http://dmytro.github.com/sherlock_os&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Source code&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/dmytro/sherlock_os&quot;&gt;http://github.com/dmytro/sherlock_os&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Enjoy!&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Memorizable password generation</title>
      <link>http://dmytro.github.com//2013/01/08/memorizable_password_generation.html</link>
      <pubDate>Tue, 08 Jan 2013 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2013/01/08/memorizable_password_generation</guid>
      <description>&lt;p&gt;I was in need to write function to generate pseudo-random strings that are easier to remember and type for a human. To use either for passwords or let&#39;s say random coupon codes.&lt;/p&gt;

&lt;p&gt;In my search I came across &lt;a href=&quot;http://snipplr.com/view/1247/&quot;&gt;this solution&lt;/a&gt;. It sure works, but does not look pretty enough.&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;random_password&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w( b c d f g h j k l m n p qu r s t v w x z )&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
      &lt;span class=&quot;sx&quot;&gt;%w( ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr )&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w( a e i o u y )&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;f&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;n&quot;&gt;f&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&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;mi&quot;&gt;1&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;to_s&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So I decided to do my own. After few modifications I came up with example below:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;rand&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&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;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;random_password&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(b c d f g h j k l m n p qu r s t v w x z ch cr fr nd ng nk nt ph pr rd sh sl sp st th tr)&lt;/span&gt; 
    &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w(a e i o u y)&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&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;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&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;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;All together it&#39;s not really any shorter, but function itself is less than half the size of the original, and as a side effect, there&#39;s also &lt;code&gt;Array.rand&lt;/code&gt; method.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>New tricks and questions with Jekyll</title>
      <link>http://dmytro.github.com//2012/12/22/jekyll-tags-pygmnents.html</link>
      <pubDate>Sat, 22 Dec 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/12/22/jekyll-tags-pygmnents</guid>
      <description>&lt;p class=&quot;italic&quot;&gt; Some new feature added to the blog, but this also brought new questions
. I&#39;ve learned something new about using Jekyll, but at the same time have some new questions not resolved yet
. &lt;/p&gt;


&lt;h2&gt;Tagging and tag cloud&lt;/h2&gt;

&lt;p&gt;I was playing a bit with different versions of tags clouds. Some of them didn&#39;t quite work for me , since they require adding Jekyll plug-ins and Github does not allow running custom plug-ins.&lt;/p&gt;

&lt;p&gt;I&#39;ve ended up with jQuery based tags. Now there&#39;s a tag cloud on pages, cross referenced links to tags list. And question:&lt;/p&gt;

&lt;h3&gt;How to make tags in pages work?&lt;/h3&gt;

&lt;p&gt;For now &lt;code&gt;site.tags&lt;/code&gt; lists only tags in blog posts, but not tags defined in other pages (for example in projects pages). however each individual page list tags when accessed by &lt;code&gt;page.tags&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ideally I want to see list of all my pages in the tags list.  Not found solution for this yet. Keep looking.&lt;/p&gt;

&lt;h3&gt;Sources&lt;/h3&gt;

&lt;p&gt;All tag cloud related stuff can be downloaded from the Github repo and is in &lt;code&gt;_includes/tag_*&lt;/code&gt; files.&lt;/p&gt;

&lt;h2&gt;Syntax highlight with Pygments&lt;/h2&gt;

&lt;p&gt;Up until today I was using Gists for inclusion (colored) pieces of code into blog posts. This works quite well, but for many small snippets can be a bit troublesome. Instead I&#39;ve discovered for myself Pygments, and this is the result:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;lineno&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;2&lt;/span&gt;   &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;lineno&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;To have that code above colored, simply add &lt;code&gt;highlight&lt;/code&gt; tags around your code as in the example below:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{ % highlight ruby linenos % }
  # ....  code here
{ % endhighlight % }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You need to do some preparation too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add &lt;code&gt;pygments: true&lt;/code&gt; in &lt;code&gt;_config.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;create CSS file and include reference to it

&lt;ul&gt;
&lt;li&gt;CSS file can be generated easily by:
&lt;code&gt;  
pygmentize -S default -f html &amp;gt; default.css
&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Nagios Checks Aggregation</title>
      <link>http://dmytro.github.com//2012/12/14/monitoring-patterns-II.html</link>
      <pubDate>Fri, 14 Dec 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/12/14/monitoring-patterns-II</guid>
      <description>&lt;p class=&#39;italic&#39;&gt;&lt;b&gt;Summary:&lt;/b&gt; Reviewed several patterns for integrated monitoring with Nagios and Nagira
. Nagira &amp;mdash; RESTful API for Nagios &amp;mdash; simplifies Nagios checks aggregation  
. For second part of the series an easy way of combining several Nagios results into aggregated check is presented.&lt;/p&gt;


&lt;h1&gt;Nagios Checks Aggregation&lt;/h1&gt;

&lt;p&gt;This kind of setup is applicable in situations where there is a need to integrate several already existing Nagios checks, but you need to aggregate information from checks into combined metric. In this case all necessary information already exists in Nagios, there is no need to read it from monitored devices, API can fetch source information from Nagios status store and write back calculated output. See diagram below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2012-12-14-nagira_nagios_checks_aggregation_flow.png&quot; alt=&quot;Simplified diagram&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;Computer Rack Prower Monitoring&lt;/h2&gt;

&lt;p&gt;An example of such setup is an electric current monitoring system.&lt;/p&gt;

&lt;p&gt;Electric current of the power lines in a computer rack are monitored by Nagios. Information from power lines is collected by SNMP. Computer racks have two power inputs for redundancy; servers, having similarly two redundant power supplies each, are connected to both power inputs.&lt;/p&gt;

&lt;p&gt;However, additional requirement exist for monitoring gross current consumed by each rack. For example, in the case of one side power source failure, the whole rack power can fail if sum total of currents is higher than power limit for the remaining source &amp;mdash; even if each of the power lines before the failure is in a green zone.&lt;/p&gt;

&lt;p&gt;In this case, to obtain data for the pair of power sources, data of each individual line is read from Nagios status database, instead of using SNMP. Data processed by script, and if total gross current of two power lines is greater than current limit for single line, status is marked as WARNING or CRITICAL. Resulting combined metric (sum of two currents) is written back to Nagios together with RAG status. All communication &amp;mdash; reads and writes &amp;mdash; are done only using web-services Nagira API.&lt;/p&gt;

&lt;h2&gt;Possible uses&lt;/h2&gt;

&lt;p&gt;Other examples where such kind of setup can be applied are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;load balanced or DNS round-robin farm of web servers, to monitor total network traffic, not only traffic on individual servers;&lt;/li&gt;
&lt;li&gt;status of clustered application &amp;mdash; if it is known, for example, that application execution requires &lt;code&gt;X&lt;/code&gt; number of servers with &lt;code&gt;Y&lt;/code&gt; CPU cores, each occupied by &lt;code&gt;Z%&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;See more&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://nagios.sourceforge.net/docs/3_0/extcommands.html&quot;&gt;Nagios External Commands interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2012/12/12/monitoring-patterns-I.html&quot;&gt;Monitoring patterns for Nagios with Nagira API - Part I&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dmytro.github.com/nagira/doc&quot;&gt;Nagira Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Monitoring Applications with RESTful API</title>
      <link>http://dmytro.github.com//2012/12/12/monitoring-patterns-I.html</link>
      <pubDate>Wed, 12 Dec 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/12/12/monitoring-patterns-I</guid>
      <description>&lt;p class=&#39;italic&#39;&gt;&lt;b&gt;Summary:&lt;/b&gt; Reviewed several patterns for integrated monitoring with Nagios and Nagira
. Nagira &amp;mdash; RESTful API for Nagios simplifies integration of distributed Nagios systems
. This is first installation of the series.&lt;/p&gt;


&lt;p&gt;Nagios is great system. Many features in Nagios are superior to many open source and commercial monitoring system. Adding HTTP based API for Nagios opens new possibilities for simpler architectures of distributed monitoring with Nagios.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://dmytro.github.com/nagira&quot;&gt;Nagira API&lt;/a&gt; provides access to system status, objects configuration in Nagios as well as provides an interface for submitting passive check results using the same HTTP protocol. This opens wider capabilities for monitoring system architecture modularity and integration.&lt;/p&gt;

&lt;h1&gt;Applications with HTTP RESTful API&lt;/h1&gt;

&lt;p&gt;Here I want to review one of the simplest patterns with Nagira - monitoring applications that have built-in HTTP API (RESTful API in our case). This pattern was implemented recently in new project &lt;a href=&quot;/NagiosForCouchbase&quot;&gt;Nagios For Couchbase&lt;/a&gt;. Similar approach can be adopted for any kind of application, that provides access to application metrics via HTTP API.&lt;/p&gt;

&lt;h1&gt;Nagios For Couchbase&lt;/h1&gt;

&lt;p&gt;&lt;a href=&quot;http://couchbase.com&quot; title=&quot;Couchbase&quot;&gt;Couchbase&lt;/a&gt; is advanced memory based NoSQL key-value database. It has its own management RESTful API and API for data access. The API provides access to most if not all of the Couchbase operational metrics. Couchbase also has nice web console with multiple graphs displaying server metrics in real time. Actually web user interface in Couchbase is implemented as &lt;a href=&quot;http://jquery.com/&quot; title=&quot;jQuery&quot;&gt;jQuery&lt;/a&gt; interface built directly on top of JSON RESTful API.&lt;/p&gt;

&lt;p&gt;Given Couchbase API combined with &lt;a href=&quot;http://dmytro.github.com/nagira&quot;&gt;Nagira API&lt;/a&gt;, setting a monitoring system becomes a simple task. Architecture of such setup is presented on the diagram below.&lt;/p&gt;

&lt;h2&gt;System Architecture&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Script connects to Couchbase API and retrieves server metrics as JSON data object (via HTTP GET request)&lt;/li&gt;
&lt;li&gt;Script process data and&lt;/li&gt;
&lt;li&gt;Sends data to Nagira API (HTTP PUT)&lt;/li&gt;
&lt;li&gt;Nagira writes to &lt;a href=&quot;http://nagios.sourceforge.net/docs/3_0/extcommands.html&quot;&gt;Nagios external command&lt;/a&gt; interface&lt;/li&gt;
&lt;li&gt;Results are then processed internally by Nagios&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;img src=&quot;/images/2012-12-12-nagios_for_couchbase.png&quot; alt=&quot;Nagios For Couchbase Diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Advantages of this architecture as far as one can see are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since only HTTP protocol involved for both retrieving data and registering results, script that runs the checks, can be in any location &amp;mdash; on Couchbase server, or on Nagios server or any other host on the network.&lt;/li&gt;
&lt;li&gt;List of couchbase servers can be retrieved from Nagios configuration itself, if corresponding host-group is configured (for example &lt;code&gt;&#39;hostgroup couchbase&#39;&lt;/code&gt;). Configuration becomes completely data driven and requires no additional changes when adding/removing Couchbase servers to the pool.&lt;/li&gt;
&lt;li&gt;JSON object containing multiple metrics can be read as with single HTTP GET request to Couchbase server, status for multiple checks can be updated similarly with single HTTP PUT to Nagira API, which produces multiple writes to Nagios command file. This reduces load on Nagios server, which is not dealing with scheduling and executing checks.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Executing Checks&lt;/h2&gt;

&lt;p&gt;How actually checks are performed will be reviewed in some of the following posts. Please come again!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Unobtrusive Git prompt for ZSH</title>
      <link>http://dmytro.github.com//2012/11/27/unobtrusive-git-prompt.html</link>
      <pubDate>Tue, 27 Nov 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/11/27/unobtrusive-git-prompt</guid>
      <description>&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;How to incorporate Git information in Zsh shell prompt in an unobtrusive manner&lt;/p&gt;

&lt;p&gt;vcs_info module for ZSH gives an ability to design nice and functional prompts for use with version control systems.
 Google can find large number of references to manuals, tutorials, blog posts and what not regrading using the module for prompt designs. In many cases, however, as to my taste resulting prompts stand in the way more than actually help. Four  or five lines shell prompts are not for me, same if prompt occupies 80% of the command line space, or it is too colorful.&lt;/p&gt;

&lt;p&gt;It took me a while, first, to learn about ZSH prompts and vcsinfo, and second to design a prompt, that I can use without too much hating it. Below are some screen-shots and code for the prompt.&lt;/p&gt;

&lt;p&gt;I am using &lt;code&gt;git&lt;/code&gt; mostly, so all my examples below are for &lt;code&gt;git&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Screen shots&lt;/h2&gt;

&lt;h3&gt;Standard prompt&lt;/h3&gt;

&lt;p&gt;When not in the git repository prompt is pretty much standard UNIX shell prompt: user name, hostname and last part of the current directory. Stepping into git repository add right part to the prompt (see below).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2012-11-27-1.png&quot; alt=&quot;Regular shell prompt - not git repository&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Small screen&lt;/h3&gt;

&lt;p&gt;Same prompt if I am in the git repository but my screen space is too small to accommodate both parts of the prompt (yellow line on the right is pane border in Tmux). Also what is really nice about right part of the prompt: if I start typing very long command and come close to the right part of the prompt, it disappears.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2012-11-27-2.png&quot; alt=&quot;Narrow screen&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Clean Git repository&lt;/h3&gt;

&lt;p&gt;When I am inside git repository right part of the prompt appears and it indicates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;git branch&lt;/li&gt;
&lt;li&gt;git repository name&lt;/li&gt;
&lt;li&gt;directory inside the git repository (last part of it)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;img src=&quot;/images/2012-11-27-3.png&quot; alt=&quot;Clean git repository&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Git repository with uncommitted changes&lt;/h3&gt;

&lt;p&gt;Right part in this case adds indication for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;U - for unstaged changes (encircled)&lt;/li&gt;
&lt;li&gt;S - for staged changes&lt;/li&gt;
&lt;li&gt;M - for stashed changes&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;img src=&quot;/images/2012-11-27-4.png&quot; alt=&quot;Repository with changes&quot; /&gt;&lt;/p&gt;

&lt;h3&gt;Action indication&lt;/h3&gt;

&lt;p&gt;Finally last screen shot shows example of unfinished merge. In red color indicated current action: merge, rebase,etc.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/2012-11-27-5.png&quot; alt=&quot;In the middle of a merge&quot; /&gt;&lt;/p&gt;

&lt;h1&gt;Source code&lt;/h1&gt;

&lt;table class=&quot;highlighttable&quot;&gt;&lt;tr&gt;&lt;td class=&quot;linenos&quot;&gt;&lt;div class=&quot;linenodiv&quot;&gt;&lt;pre&gt;&lt;code class=&quot;bash&quot;&gt; 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;autoload -Uz vcs_info
zstyle &lt;span class=&quot;s1&quot;&gt;&amp;#39;:vcs_info:*&amp;#39;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;git
precmd&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    vcs_info
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
 
setopt prompt_subst
zstyle &lt;span class=&quot;s1&quot;&gt;&amp;#39;:vcs_info:git:*&amp;#39;&lt;/span&gt; check-for-changes &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
zstyle &lt;span class=&quot;s1&quot;&gt;&amp;#39;:vcs_info:*&amp;#39;&lt;/span&gt;    formats &lt;span class=&quot;s2&quot;&gt;&amp;quot;%f[%%n@%%m %1~] $ &amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;%f%a %F{3}%m%u%c %f%b:%r/%S&amp;quot;&lt;/span&gt; 
zstyle &lt;span class=&quot;s1&quot;&gt;&amp;#39;:vcs_info:*&amp;#39;&lt;/span&gt;    nvcsformats   &lt;span class=&quot;s2&quot;&gt;&amp;quot;%f[%n@%m %1~]$ &amp;quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
zstyle &lt;span class=&quot;s1&quot;&gt;&amp;#39;:vcs_info:*&amp;#39;&lt;/span&gt;    actionformats &lt;span class=&quot;s1&quot;&gt;&amp;#39;%F{5}(%f%s%F{5})%F{3}-%F{5}[%F{2}%b%F{3}|%F{1}%a%F{5}]%f &amp;#39;&lt;/span&gt;
 
&lt;span class=&quot;nv&quot;&gt;PROMPT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;${vcs_info_msg_0_}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;RPROMPT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;${vcs_info_msg_1_}&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;


&lt;p&gt;Short explanation for the code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each &lt;code&gt;zstyle &#39;:vcs_info:*&#39;&lt;/code&gt; line sets style for vcs_info messages. There are 2 messages configured: &lt;code&gt;vcs_info_msg_0_&lt;/code&gt; and &lt;code&gt;vcs_info_msg_1_&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In each line &lt;code&gt;vcs_info_msg_0_&lt;/code&gt; and &lt;code&gt;vcs_info_msg_1_&lt;/code&gt; are first and second arguments in each definition. I.e., for example on line 9 &lt;code&gt;&quot;%f[%%n@%%m %1~] $ &quot;&lt;/code&gt; is msg 0, and &lt;code&gt;&quot;%f%a %F{3}%m%u%c %f%b:%r/%S&quot;&lt;/code&gt; is msg 1.

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;formats&lt;/code&gt; defines style for prompt in inside git repository&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvcsformats&lt;/code&gt; - same for non git directories&lt;/li&gt;
&lt;li&gt;&lt;code&gt;actionformats&lt;/code&gt; - for git actions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Left and right parts of prompt are set on lines 13 and 14 correspondingly to display &lt;code&gt;vcs_info_msg_0_&lt;/code&gt; on the left and &lt;code&gt;vcs_info_msg_1_&lt;/code&gt; on the right.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;References&lt;/h1&gt;

&lt;p&gt;Below are links to some of the resources I&#39;ve used. They can be used as reference or simply as example of different designs of the prompt.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://arjanvandergaag.nl/blog/customize-zsh-prompt-with-vcs-info.html&quot;&gt;Customize your ZSH prompt with vcs_info&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://briancarper.net/blog/570/git-info-in-your-zsh-prompt&quot;&gt;Git info in your ZSH Prompt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/1128496/to-get-a-prompt-which-indicates-git-branch-in-zsh&quot;&gt;To get a prompt which indicates Git-branch in Zsh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Opening multiple Tmux panes in the same directory</title>
      <link>http://dmytro.github.com//2012/11/22/open-new-tabs-in-same-dir-in-tmux.html</link>
      <pubDate>Thu, 22 Nov 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/11/22/open-new-tabs-in-same-dir-in-tmux</guid>
      <description>&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;This small snippet of code allows opening windows/panes inside tmux in the same UNIX directory.&lt;/p&gt;

&lt;br clear=&#39;all&#39;&gt;


&lt;h2&gt;Source code&lt;/h2&gt;

&lt;script src=&quot;https://gist.github.com/4129656.js?file=tmux_pwd.sh&quot;&gt;&lt;/script&gt;


&lt;p&gt;When working on project I quite often want to open new window or pane in Tmux in the same directory where I am now at the moment. Before I figured out how to do it, it was like this: open new pane, &lt;code&gt;cd &amp;lt;...&amp;gt;&lt;/code&gt;, &lt;code&gt;cd &amp;lt;...&amp;gt;&lt;/code&gt;, &lt;code&gt;cd &amp;lt;...&amp;gt;&lt;/code&gt;.  Even with single &lt;code&gt;cd&lt;/code&gt; and tab completion, navigating through deeply nested project tree can be not that easy.&lt;/p&gt;

&lt;h2&gt;Solution&lt;/h2&gt;

&lt;p&gt;Here&#39;s the small shell function and alias to help.&lt;/p&gt;

&lt;h3&gt;This is how I use it&lt;/h3&gt;

&lt;p&gt;When I want new window or pane to be created and &lt;code&gt;cd&lt;/code&gt; to that dir automatically I simply type &lt;code&gt;pwd&lt;/code&gt; and after this open new window/pane.&lt;/p&gt;

&lt;h3&gt;And this is how it works&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tmux_pwd&lt;/code&gt; function executed in your current directory simply sets option for window in your current Tmux session to use this directory as default (lines 3 and 4 of the gist).

&lt;ul&gt;
&lt;li&gt;Line 3 detects current session of the tmux.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I don&#39;t want this function to be executed in the shell which does not run under Tmux. Hence the line No 1 in gist.&lt;/li&gt;
&lt;li&gt;And I don&#39;t want all my new windows to be opened in this directory forever. I have my &#39;global&#39; default directory, which is &lt;code&gt;~/Development&lt;/code&gt;, and this is where all my windows usually open. So, there&#39;s a &#39;timeout&#39; setting to set my default directory back after 5 mins. Lines 5 and 6.&lt;/li&gt;
&lt;li&gt;And finally there&#39;s an alias, on line 8.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I&#39;ve added this to my zsh functions, but I don&#39;t see why it shouldn&#39;t work in another shells like Bash.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My Really Low Tech Music Player</title>
      <link>http://dmytro.github.com//2012/11/20/my-low-tech-music-player.html</link>
      <pubDate>Tue, 20 Nov 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/11/20/my-low-tech-music-player</guid>
      <description>&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;Small script to play music collection from commands line.&lt;/p&gt;

&lt;p&gt;Really minimalistic Ruby script to shuffle audio files and play them randomly form disk
 No GUI, very little contol, just enough for simply playing music. Script randomizes list of files and plays them in random order, &lt;code&gt;Ctrl-C&lt;/code&gt; skips current song and goes to the next, &lt;code&gt;Ctrl-Z&lt;/code&gt; exits script.&lt;/p&gt;

&lt;h1&gt;Source code&lt;/h1&gt;

&lt;script src=&quot;https://gist.github.com/4115472.js?file=play.rb&quot;&gt;&lt;/script&gt;


&lt;h2&gt;Configuration&lt;/h2&gt;

&lt;p&gt;Before using script generate list of songs with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;find PATH/TO/THE/LIBARY -type f &amp;gt; music.list
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Creating &quot;playlists&quot; is just &lt;code&gt;grep&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;grep Beatles music.list &amp;gt; favorites.list
grep &quot;Deep Purple&quot; music.list &amp;gt;&amp;gt; favorites.list
&lt;/code&gt;&lt;/pre&gt;
</description>
    </item>
    
    <item>
      <title>Start multiple synchronized SSH connections with Tmux</title>
      <link>http://dmytro.github.com//2012/10/31/ssh-multi.html</link>
      <pubDate>Wed, 31 Oct 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/10/31/ssh-multi</guid>
      <description>&lt;br clear=&#39;all&#39;&gt;


&lt;h1&gt;Summary&lt;/h1&gt;

&lt;p&gt;Small shell script to start multiple connections to SSH servers with synchronized keyboard.&lt;/p&gt;

&lt;p&gt;If you need to connect to multiple SSH machines and perform some operation on all of them, there are many ways to do this. Typically regular sysadmin would write simple &lt;code&gt;for&lt;/code&gt; one-liner in shell:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;for i in $HOSTS; do &amp;lt;....&amp;gt; done
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&#39;s OK for simple command or couple of commands. But, if commands produce verbose output, or you want to see what&#39;s happening in between your commands, this approach can be more troublesome. Or, for example, your ssh keys are not set and you&#39;d need to type password for each SSH prompt.&lt;/p&gt;

&lt;h2&gt;Tmux way&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;tmux&lt;/code&gt; you can do it in a different way. If you haven&#39;t started with &lt;code&gt;tmux&lt;/code&gt; yet, there&#39;s a good reason to do it.&lt;/p&gt;

&lt;p&gt;This script allows with single command open multiple equally split-panes in Tmux window and synchronizes keyboard input in all windows.
 Anything you type will go at the same time to all &lt;code&gt;tmux&lt;/code&gt; panes and you will see output of commands in all windows as they are executed. Any time it is you can break keyboard sync between panes if you need to execute something in single shell only, then you can sync again and continue as before.&lt;/p&gt;

&lt;p&gt;Full text of the script is provided in the Gist below. It is based on solution I&#39;ve found online, a bit simplified and extended to accept list of hosts from command line.&lt;/p&gt;

&lt;p&gt;I usually run it as:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-multi myhost1 myhost2 myhost3 myhost4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or for some groups of hosts, I put list into plain text file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-multi $(cat list-of-hosts)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The script is included in &lt;a href=&quot;http://github.com/dmytro/dotfiles&quot;&gt;dotfiles&lt;/a&gt; repository. You can eiterh copy-paste from included Gist, or simply get the whole thing, by cloning o downloading it using links below.&lt;/p&gt;

&lt;h2&gt;See also &lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/2012/07/18/iterm-tmux-emacs.html&quot;&gt;Blog post&lt;/a&gt; regarding Tmux environment configuration&lt;/p&gt;

&lt;h1&gt;Script source code&lt;/h1&gt;

&lt;script src=&quot;https://gist.github.com/3984680.js&quot;&gt; &lt;/script&gt;



</description>
    </item>
    
    <item>
      <title>What's in the name -- Nagira?</title>
      <link>http://dmytro.github.com//2012/10/11/nagira-concert.html</link>
      <pubDate>Thu, 11 Oct 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/10/11/nagira-concert</guid>
      <description>&lt;p&gt;&lt;em&gt;When a while ago I was selecting name for my new project I didn&amp;#8217;t have slightest idea that Nagira is actually somebody&amp;#8217;s name.&lt;/p&gt;
&lt;p&gt;Nagira sounded to me as a name, I thought it was more like a female name, maybe of Persian origins. It was a bit of surprize for me to type &amp;#8216;nagira&amp;#8217; in google and see more than 100 000 hits.&lt;br /&gt;
&lt;/em&gt;&lt;/p&gt;
&lt;img src=&quot;/images/2012-10-11-nagira-concert-clip.png&quot; alt=&quot;&quot; /&gt;
&lt;p&gt;So, I&amp;#8217;ve discovered that &amp;#8216;Nagira&amp;#8217; &lt;em&gt;&lt;b&gt;is a name&lt;/b&gt;&lt;/em&gt;, but not female, and not Persian, but rather Japanese and male.&lt;/p&gt;
&lt;p&gt;So, today on  my way to work I see this real life example &amp;#8211; Nagira&amp;#8217;s concert in Asakusa Jinja.&lt;/p&gt;
&lt;p&gt;Below you can see references to the project of mine: Nagira &amp;#8212; Nagios RESTful &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;img src=&quot;/images/2012-10-11-nagira-concert.png&quot; alt=&quot;&quot; /&gt;</description>
    </item>
    
    <item>
      <title>My first gem and first Rubygems impressions</title>
      <link>http://dmytro.github.com//2012/09/09/my-first-gem.html</link>
      <pubDate>Sun, 09 Sep 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/09/09/my-first-gem</guid>
      <description>&lt;p&gt;&lt;em&gt;Two days ago I&#39;ve produced and published my first gem.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;Process ? Simple!&lt;/h1&gt;

&lt;p&gt;Being from the Perl CPAN background I was prepared for something more laborious: tar&#39;ing and gzip&#39;ing, and uploading files to web server. Moving file(s) around, maintaining archives and deleting old versions (not that I&#39;ve got any old versions yet).&lt;/p&gt;

&lt;p&gt;However, in the end it was much simpler. Even little disappointingly too simple. After you finished writing gemspec file, you simply do &lt;code&gt;gem build [gemfile]&lt;/code&gt; to build it, &lt;code&gt;gem install ...&lt;/code&gt; to install and test locally and &lt;code&gt;gem push [just-built.gem]&lt;/code&gt; to push it to &amp;lt;http:://rubygems.org&gt; . You&#39;d need to create your Rubygems account first.&lt;/p&gt;

&lt;p&gt;After last action -- having answered command line prompt questions about your Rubygems login -- few seconds later you think: &quot;That&#39;s all!?&quot; Yes, that&#39;s it. Your gem released and can be installed simply by &lt;code&gt;gem install [name]&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;Well done - Rubygems&lt;/h1&gt;

&lt;p&gt;After registering and playing a little bit more with Rubygems, I&#39;ve found some nice features.&lt;/p&gt;

&lt;h2&gt;Documentation&lt;/h2&gt;

&lt;p&gt;Rubygems displays YARD-formatted documentation for the gem.  I am not sure if it&#39;s by default or because I had &lt;code&gt;rake doc&lt;/code&gt; task in my Rakefile, that call &lt;code&gt;yarddoc&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Stats&lt;/h2&gt;

&lt;p&gt;Looking 2 days after uploading gem I discovered this &lt;a href=&quot;https://rubygems.org/gems/rspec_normalized_hash/stats&quot;&gt;download stats&lt;/a&gt;. Of course, you&#39;d like to know, whether somebody likes your work or even did at least somebody download at all ?&lt;/p&gt;

&lt;h1&gt;What about CPAN?&lt;/h1&gt;

&lt;p&gt;What I found missing in Rubygems compared to Perl CPAN, or at least haven&#39;t found it yet with my limited Rubygems experience.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Testing&lt;/strong&gt;  After each update of CPAN module I&#39;ve used to receive automated test results. Module automatically submitted to testing framework and your test are being run in multiple exnvironments. Good for testing on platforms that I don&#39;t have access too -- Windows or  something like AIX/HP-UX, or testing for missing dependencies -- did I have that_nice.gem installed on my system, but didn&#39;t include it in dependency list?. However, latter case is rather less important with &lt;code&gt;bundler&lt;/code&gt; and &lt;code&gt;Gemfile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Namespacing&lt;/strong&gt; CPAN allows you to apply and register namespace for the module(s) and families of modules. By setting some rules on namings Perl does it easier to find what you really need going from top to bottom. This is what I really miss in Ruby community - searching for right gems can be simpler then it is now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ticketing&lt;/strong&gt; RT (AKA Request Tracker) is ticketing system developed by Perl programmers and it is used by Perl programmers. What can you say more? It is ticketing system used by all Perl contributors. Will be nice to have something similar for Ruby and Rubygems.&lt;/li&gt;
&lt;/ul&gt;


&lt;h1&gt;What I have released?&lt;/h1&gt;

&lt;p&gt;Hopefully something useful. It&#39;s an RSpec test suite for what I call Normalized Hash. Description of Normalized Hash and more info about the specs are in &lt;a href=&quot;/rspec_normalized_hash/&quot;&gt;github project&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>RT4 can be less ugly</title>
      <link>http://dmytro.github.com//2012/07/18/rt-custom-css.html</link>
      <pubDate>Wed, 18 Jul 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/07/18/rt-custom-css</guid>
      <description>&lt;p&gt;Default ticket display in &lt;a href=&quot;http://bestpractical.com/rt/&quot; title=&quot;Request Tracker&quot;&gt;RT&lt;/a&gt; is really ugly &amp;#8211; all system messages (actions) are shown exactly the same way as user actions. Luckily RT4 has added possibility to have custom user &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt;. This addition to &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; make system actions to stand out less: smaller fonts, and less contrast.&lt;/p&gt;
&lt;p&gt;Stuff that&amp;#8217;s added is all .ticket-transaction entries at the bottom.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;br clear=&#39;all&#39;&gt;
&lt;script src=&quot;https://gist.github.com/3135235.js?file=rt.css&quot;&gt;&lt;/script&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Now I've got my environment ...</title>
      <link>http://dmytro.github.com//2012/07/18/iterm-tmux-emacs.html</link>
      <pubDate>Wed, 18 Jul 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/07/18/iterm-tmux-emacs</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;br /&gt;
It looks like I finally have an environment I am satisfied with and I have tools to manage it. &lt;br /&gt;
&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Long previous years I had set of my own configuration files that I carried with me from one environment (usually associated with new job) to another. These were huge &lt;code&gt;.emacs&lt;/code&gt; file, even bigger &lt;code&gt;.fvwm2rc&lt;/code&gt; file, lot of additional e-Lisp files, &lt;code&gt;.bashrc&lt;/code&gt; and so on.&lt;/p&gt;
&lt;p&gt;Management system was simple: got a job &amp;#8594; send yourself email from home with lot of attachments &amp;#8594; save to home directory &amp;#8594; add changes. Usually after &amp;#8216;add changes&amp;#8217; step, one had to copy changes back to home files.&lt;/p&gt;
&lt;p&gt;Now, I&amp;#8217;ve got my own copy of &lt;a href=&quot;git@github.com:dmytro/dotfiles.git&quot;&gt;dotfiles&lt;/a&gt; on Github and that makes life enjoyable again. There&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt; file that explains most what you need to know to start using it.&lt;/p&gt;
&lt;p&gt;At about the same time I&amp;#8217;ve discovered several new things &amp;#8211; &lt;a href=&quot;http://www.iterm2.com/#/section/home&quot;&gt;&lt;code&gt;iTerm2&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://tmux.sourceforge.net/&quot;&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;iTerm2 + tmux + emacs&lt;/h1&gt;
&lt;p&gt;Making navigation in all three of the above if not the same then at least similar makes life much easier. Just to make things clearer: I am not a mouse person, and by navigation I mean using keyboard.&lt;/p&gt;
&lt;p&gt;Since I am mostly in the Mac now, I am using &lt;a href=&quot;http://www.fvwm.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;FWVM&lt;/span&gt;&lt;/a&gt; much less, and navigating in it is less concern for me.&lt;/p&gt;
&lt;p&gt;Additionally navigation includes more things then jst switching from window to window. There&amp;#8217;s navigating on command line: search command history, search and scroll forth/back in scrollback buffer, etc.&lt;/p&gt;
&lt;h2&gt;Navigating in iTerm2 and tmux&lt;/h2&gt;
&lt;p&gt;Most of the keys set by default in &lt;code&gt;iTerm2&lt;/code&gt; (Cmd-&lt;num&gt;, Cmd-End?Home etc.) are unused when &lt;code&gt;iTerm2&lt;/code&gt; used in combination with &lt;code&gt;tmux&lt;/code&gt;. For example, when using &lt;code&gt;tmux&lt;/code&gt; scroll buffer, &lt;code&gt;iTerm2&lt;/code&gt; scoll buffer cannot be used and only messes things up. So, I actually set &lt;code&gt;iTerm2&lt;/code&gt; buffer size to 0 &amp;#8212; this removes &lt;code&gt;iTerm2&lt;/code&gt; scroill bar as well, and this also gives a bit more screen space.&lt;/p&gt;
&lt;p&gt;Similarly with all other features. To say the truth I actually use only 2 features of &lt;code&gt;iTerm2&lt;/code&gt;: full-scrrn mode and ability to map keys to send text strings or sequences of hex codes.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve deleted all default key mappings from &lt;code&gt;iTerm2&lt;/code&gt; and remapped them to send &lt;code&gt;tmux&lt;/code&gt; commands instead. There are 2 places you have to do this:&lt;/p&gt;
&lt;h3&gt;Profiles keymaps&lt;/h3&gt;
&lt;p&gt;By default &lt;code&gt;iTerm2&lt;/code&gt; loads &lt;code&gt;xterm&lt;/code&gt; default key mappings. They intervene with global key mappings and override them. The simplest solution I&amp;#8217;ve found to be simply delete all of them. I haven&amp;#8217;t run into any problems as of yet related to this, &lt;span class=&quot;caps&quot;&gt;YMMV&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/2012-07-18-tmux-profiles.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Go to &lt;code&gt;iTerm2&lt;/code&gt; preferences&lt;/p&gt;
&lt;h3&gt;Default (global) keymaps&lt;/h3&gt;
&lt;p&gt;Same with the global key mappings &amp;#8212; I use none of them in &lt;code&gt;tmux&lt;/code&gt; &amp;#8212; I deleted all defaults and set my own.&lt;/p&gt;
&lt;p&gt;However, here instead of doing all manually, on all macs, I can reuse my config by saving presets to file, and by re-imporing it into &lt;code&gt;iTerm2&lt;/code&gt; preferences. I can also use github and dotfile repository to track changes and share presets across all environments.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve added 2 Rake tasks for exporting, importing &lt;code&gt;iTerm2&lt;/code&gt; global key presets:&lt;/p&gt;
&lt;pre&gt;
    rake iterm:keys:export  # Save global key mapping to file
    rake iterm:keys:import  # Load global key mapping from file to iTerm2 defaults
&lt;/pre&gt;
&lt;p&gt;Actual command that is executed uses McOSX &lt;code&gt;defaults&lt;/code&gt; command:&lt;/p&gt;
&lt;pre&gt;
    defaults read ~/Library/Preferences/com.googlecode.iTerm2 GlobalKeyMap &amp;gt; iTerm2/GlobalKeyMap
&lt;/pre&gt;
&lt;h2&gt;Navigation key mappings&lt;/h2&gt;
&lt;p&gt;This is a list of key mappings configured. In the table below &amp;#8216;screen&amp;#8217; refers to:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;pane for &lt;code&gt;tmux&lt;/code&gt;&lt;/li&gt;
	&lt;li&gt;window for &lt;code&gt;emacs&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since &lt;code&gt;emacs&lt;/code&gt; does not do distiction between Option and Command keys on Mac, &amp;#8216;M-&amp;#8217; in &lt;code&gt;emacs&lt;/code&gt; column refers to Meta key, which is Option or Command. For the same reason for screen jumping I had to use Ctrl-&lt;arrow&gt; in &lt;code&gt;Emacs&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Navigating windows&lt;/h3&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Function            &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;tmux&lt;/code&gt;       &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;iTerm2&lt;/code&gt;      &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;emacs&lt;/code&gt;    &lt;/th&gt;
		&lt;th&gt;Zsh                 &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go screen left        &lt;/td&gt;
		&lt;td&gt; ` Left         &lt;/td&gt;
		&lt;td&gt; Cmd-Left        &lt;/td&gt;
		&lt;td&gt; Ctrl-Left    &lt;/td&gt;
		&lt;td&gt; &amp;#8211;                     &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go screen right       &lt;/td&gt;
		&lt;td&gt; ` Right        &lt;/td&gt;
		&lt;td&gt; Cmd-Right       &lt;/td&gt;
		&lt;td&gt; Ctrl-Right   &lt;/td&gt;
		&lt;td&gt; &amp;#8211;                     &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go screen up          &lt;/td&gt;
		&lt;td&gt; ` Up           &lt;/td&gt;
		&lt;td&gt; Cmd-Up          &lt;/td&gt;
		&lt;td&gt; Ctrl-Up      &lt;/td&gt;
		&lt;td&gt; &amp;#8211;                     &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go screen down        &lt;/td&gt;
		&lt;td&gt; ` Down         &lt;/td&gt;
		&lt;td&gt; Cmd-Down        &lt;/td&gt;
		&lt;td&gt; Ctrl-Down    &lt;/td&gt;
		&lt;td&gt; &amp;#8211;                     &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go previous screen    &lt;/td&gt;
		&lt;td&gt; ` ;            &lt;/td&gt;
		&lt;td&gt; Cmd-` and Cmd-; &lt;/td&gt;
		&lt;td&gt; Cmd-Up       &lt;/td&gt;
		&lt;td&gt; &amp;#8211;                     &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Word forward          &lt;/td&gt;
		&lt;td&gt; &amp;#8211;              &lt;/td&gt;
		&lt;td&gt; Option-Right    &lt;/td&gt;
		&lt;td&gt; M-Right      &lt;/td&gt;
		&lt;td&gt; Option-Right          &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Word backward         &lt;/td&gt;
		&lt;td&gt; &amp;#8211;              &lt;/td&gt;
		&lt;td&gt; Option-Left     &lt;/td&gt;
		&lt;td&gt; M-Left       &lt;/td&gt;
		&lt;td&gt; Option-Left           &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Delete word forward   &lt;/td&gt;
		&lt;td&gt; &amp;#8211;              &lt;/td&gt;
		&lt;td&gt; Cmd-d           &lt;/td&gt;
		&lt;td&gt; M-d          &lt;/td&gt;
		&lt;td&gt; Cmd-d                 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Delete word backward  &lt;/td&gt;
		&lt;td&gt; &amp;#8211;              &lt;/td&gt;
		&lt;td&gt; Cdm-Delete      &lt;/td&gt;
		&lt;td&gt; M-Delete     &lt;/td&gt;
		&lt;td&gt; Cmd-Delete            &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;h3&gt;Windows operations&lt;/h3&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Function            &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;tmux&lt;/code&gt;       &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;iTerm2&lt;/code&gt;            &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Go to window Number   &lt;/td&gt;
		&lt;td&gt; ` number       &lt;/td&gt;
		&lt;td&gt; Cmd-&amp;#8220;number&amp;#8221;          &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Toggle panes sync     &lt;/td&gt;
		&lt;td&gt; ` S            &lt;/td&gt;
		&lt;td&gt; Cmd-S                 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Split horizontally    &lt;/td&gt;
		&lt;td&gt; ` &amp;#8220;-&amp;#8221;          &lt;/td&gt;
		&lt;td&gt; Cmd-&amp;#8220;-&amp;#8221;               &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Split vertically      &lt;/td&gt;
		&lt;td&gt; ` \            &lt;/td&gt;
		&lt;td&gt; Cmd-&amp;#8220;\&amp;#8221;               &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Next window           &lt;/td&gt;
		&lt;td&gt; ` n            &lt;/td&gt;
		&lt;td&gt; Cmd-Option-Right      &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Prev window           &lt;/td&gt;
		&lt;td&gt; ` p            &lt;/td&gt;
		&lt;td&gt; Cmd-Option-Left       &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; &lt;code&gt;Tmux&lt;/code&gt; Help           &lt;/td&gt;
		&lt;td&gt; ` ?            &lt;/td&gt;
		&lt;td&gt; Cmd-h                 &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;h3&gt;Tmux selection mode&lt;/h3&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Function                                 &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;tmux&lt;/code&gt;            &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;iTerm2&lt;/code&gt;   &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Mouse selection ON                         &lt;/td&gt;
		&lt;td&gt; `+m                 &lt;/td&gt;
		&lt;td&gt; Cmd-m        &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Mouse selection &lt;span class=&quot;caps&quot;&gt;OFF&lt;/span&gt;                        &lt;/td&gt;
		&lt;td&gt; `+M                 &lt;/td&gt;
		&lt;td&gt; Cmd-M        &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Start &lt;code&gt;tmux&lt;/code&gt; selection mode                &lt;/td&gt;
		&lt;td&gt; `+[                 &lt;/td&gt;
		&lt;td&gt; Cmd-[        &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Copy &lt;code&gt;tmux&lt;/code&gt; selection to system clipboard  &lt;/td&gt;
		&lt;td&gt; `+Ctrl-]            &lt;/td&gt;
		&lt;td&gt; Ctrl-Cmd-]   &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Paste &lt;code&gt;tmux&lt;/code&gt; selection                     &lt;/td&gt;
		&lt;td&gt; `+]                 &lt;/td&gt;
		&lt;td&gt; Cmd-]        &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Start selection mode, scroll page up       &lt;/td&gt;
		&lt;td&gt; `+PgUp              &lt;/td&gt;
		&lt;td&gt; (&lt;span class=&quot;caps&quot;&gt;TODO&lt;/span&gt;)       &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;h3&gt;Various tmux actions&lt;/h3&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;th&gt;Function                                 &lt;/th&gt;
		&lt;th&gt;&lt;code&gt;tmux&lt;/code&gt;            &lt;/th&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Prefix                                     &lt;/td&gt;
		&lt;td&gt; `                   &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Change prefix to Ctrl-o                    &lt;/td&gt;
		&lt;td&gt; F12                 &lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td&gt; Change prefix to &amp;#8220;`&amp;#8221;                       &lt;/td&gt;
		&lt;td&gt; F11                 &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It is good to have option of disabling &amp;#8220;`&amp;#8221; as &lt;code&gt;tmux&lt;/code&gt; prefix key for cut-and-paste shell scripts into terminal. Most of the mappinngs will not work when prefix changed to Ctrl-o, since in many cases &lt;code&gt;iTerm2&lt;/code&gt; keystrokes send text &amp;#8220;`&amp;#8221;+something.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Can one little second kill your servers?</title>
      <link>http://dmytro.github.com//2012/07/02/can-one-second-kill.html</link>
      <pubDate>Mon, 02 Jul 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/07/02/can-one-second-kill</guid>
      <description>&lt;p&gt;Actually &amp;#8212; yes.&lt;/p&gt;
&lt;p&gt;Early Saturday morning Japan time most of the servers in the company where I work now started to act. &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; usage spiked to 100-200% while no load was actually hitting the servers.&lt;br /&gt;
 Mysql on restart used again insane amount of &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt;. At the same time, servers were quite responsive and acting like normal.&lt;/p&gt;
&lt;p&gt;After some time later reports started to appear in Google search&amp;#8230; Reports were talking about &amp;#8230; &lt;i&gt;leap second&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;At the mid-night &lt;span class=&quot;caps&quot;&gt;GMT&lt;/span&gt; time on Jun 30, 2012 extra second was added &amp;#8212; leap second. &lt;span class=&quot;caps&quot;&gt;NTP&lt;/span&gt; supposed to have been picked up that small change, but it did not. Most of the Linux servers&amp;#8217; CPUs went into timeless cycle: check flag (&amp;#8216;leap second&amp;#8217; flag in &lt;span class=&quot;caps&quot;&gt;NTP&lt;/span&gt; protocol), set flag, check flag, reset flag &amp;#8230;&lt;/p&gt;
&lt;p&gt;The funniest thing about all this story is sequence of commands you&amp;#8217;d have to run to fix the issue:&lt;/p&gt;
&lt;pre&gt;
        ntp stop
        ntpdate ntp.pool.org 
        ntp start
&lt;/pre&gt;
&lt;p&gt;Or even this (!!) :&lt;/p&gt;
&lt;pre&gt;
        ntp stop
        date -s &quot;`date`&quot;
        ntp start
&lt;/pre&gt;
</description>
    </item>
    
    <item>
      <title>Making Debian 6.x play nicely with Cobbler</title>
      <link>http://dmytro.github.com//2012/06/21/debian_cobbler.html</link>
      <pubDate>Thu, 21 Jun 2012 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2012/06/21/debian_cobbler</guid>
      <description>






&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;Cobbler works OK when client system is RedHat-based &amp;#8212; &lt;span class=&quot;caps&quot;&gt;RHEL&lt;/span&gt; or CentOS &amp;#8212; but support for other OS&amp;#8217;s is less than perfect. Recently I had to configure Debian (currently at &lt;code&gt;6.0.5&lt;/code&gt;) to be built by Cobbler, and here is a &lt;span class=&quot;caps&quot;&gt;HOWTO&lt;/span&gt; for making it work.&lt;/p&gt;
&lt;h1&gt;Problems&lt;/h1&gt;
&lt;p&gt;There are several issues when making Debian to be able to be installed by Cobbler.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;First of all current (6.0.5) Debian netboot installer is broken. It   fails with &amp;#8220;No disks found&amp;#8221; message, reason being that no &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;, &lt;span class=&quot;caps&quot;&gt;SCSI&lt;/span&gt;   or &lt;span class=&quot;caps&quot;&gt;SATA&lt;/span&gt; udebs are included with netboot installer. This &lt;a href=&quot;http://forums.debian.net/viewtopic.php?f=17&amp;amp;t=76050&quot;&gt;has been   reported&lt;/a&gt; but not fixed yet. The only way to fix this   issue seems to be rebuild the installer from scratch.&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
	&lt;li&gt;Additionally I wanted to avoid any questions asked by installer&amp;#8212;make it fully unattended. This requires some addition to Debian&amp;#8217;s netboot &lt;code&gt;initrd&lt;/code&gt; file. Otherwise even if you provide seed file it keeps stopping and asks you about keyboard layout and network configuration. Reason is&amp;#8212;these questions have to be asked before network is up and seed file from network can be loaded.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Process&lt;/h1&gt;
&lt;h2&gt;Cobbler server&lt;/h2&gt;
&lt;p&gt;On your Cobbler server first of all import Debian as usual: &lt;code&gt;cobbler import --breed=debian --name=Debian6.0.5 --path=...&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Build server for the Installer&lt;/h2&gt;
&lt;p&gt;Build your Debian installer build server. Setup system using instruction at &lt;a href=&quot;http://wiki.debian.org/DebianInstaller/Build&quot;&gt;Debian Installer page&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This involves installing dependencies, checking out Debian Installer and installing dependencies again (in some cases).&lt;/p&gt;
&lt;h3&gt;Install dependencies&lt;/h3&gt;
&lt;p&gt;Use &lt;a href=&quot;http://wiki.debian.org/DebianInstaller/CheckOut&quot;&gt;Debian Installer Checkout&lt;/a&gt; page for the reference.&lt;/p&gt;
&lt;p&gt;Installing installer basically performed with following commands:&lt;/p&gt;
&lt;pre&gt;
 svn co svn://svn.debian.org/svn/d-i/trunk debian-installer
 cd debian-installer
 scripts/git-setup           
 mr -p checkout
&lt;/pre&gt;

&lt;h3&gt;Check dependencies are satisfied&lt;/h3&gt;
&lt;pre&gt;
 apt-get build-dep debian-installer
 dpkg-checkbuilddeps
&lt;/pre&gt;
&lt;p&gt;In my case lat command complained about missing &lt;code&gt;win32-loader&lt;/code&gt; &lt;code&gt;&amp;gt;0.7.2&lt;/code&gt;.  This is package from &lt;code&gt;Wheeze (7.0)&lt;/code&gt; but Squeeze has only &lt;code&gt;0.6x&lt;/code&gt;. I had to download &lt;code&gt;deb&lt;/code&gt; file from &lt;a href=&quot;http://ftp.yz.yamagata-u.ac.jp/debian/pool/main/w/win32-loader/win32-loader_0.7.4.3_all.deb&quot;&gt;Wheezy mirror&lt;/a&gt; and install it manually:&lt;/p&gt;
&lt;pre&gt;
 wget http://ftp.yz.yamagata-u.ac.jp/debian/pool/main/w/win32-loader/win32-loader_0.7.4.3_all.deb
 dpkg --install win32-loader_0.7.4.3_all.deb
&lt;/pre&gt;
&lt;h3&gt;Add/change configuration files&lt;/h3&gt;
&lt;p&gt;All configuration files reside below &lt;code&gt;debian-installer/installer/build&lt;/code&gt; directory. All paths below refer to sub-directories starting from this point.&lt;/p&gt;
&lt;h4&gt;Kernel configuration&lt;/h4&gt;
&lt;p&gt;First is kernel, installer image must have same kernel version as build host, since kernel and modules are copied from build host to installer image. Make sure this is set correctly in &lt;code&gt;./config/&amp;lt;arch&amp;gt;.cfg&lt;/code&gt;. In my case, I am building 64-bit installer, therefore architecture config file is &lt;code&gt;./config/amd64.cfg&lt;/code&gt;:&lt;/p&gt;
&lt;script
src=&quot;https://gist.github.com/2964138.js?file=config__amd64.cfg&quot;&gt;&lt;/script&gt;&lt;h4&gt;Missing udebs&lt;/h4&gt;
&lt;p&gt;Next part is where actually broken installer fixed, here we will add missing drivers.&lt;/p&gt;
&lt;p&gt;Netboot package lists are configured by files in &lt;code&gt;pkg-lists/netboot&lt;/code&gt; directory. To make the change work for all architectures the easiest is to change &lt;code&gt;pkg-lists/netboot/common&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;Below is list of additions to the file. Full listing of &lt;code&gt;pkg-lists/netboot/common&lt;/code&gt; file can be found in &lt;a href=&quot;https://gist.github.com/raw/2964138/ad9cd1fe809fad917687bbe0575824ede047abda/pkg-lists__netboot__common&quot;&gt;Github gist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;script src=&quot;https://gist.github.com/2964138.js?file=pkg-lists__netboot__common__additions.cfg&quot;&gt;&lt;/script&gt;&lt;/p&gt;
&lt;h4&gt;Pre-seeding&lt;/h4&gt;
&lt;p&gt;Automation of Cobbler installs is done by &lt;a href=&quot;http://wiki.debian.org/DebianInstaller/Preseed&quot;&gt;preseed&lt;/a&gt; file. Preseed file can resign on Cobbler server and configured by &lt;code&gt;--kickstart&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;However when using netboot installer there are some configuration options that need to be set before kickstart is downloaded from Cobbler: console keyboard, language during installation etc. For this reason they need to be in &lt;code&gt;initrd&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;There are several ways to do this. If you are using pre-built installer, you can add &lt;code&gt;preseed.cfg&lt;/code&gt; file to it. Simple &lt;a href=&quot;https://gist.github.com/2964138#file_make_preseed.sh&quot;&gt;shell script&lt;/a&gt; can help with this.&lt;/p&gt;
&lt;p&gt;But, since we need to make initrd ourselves anyway, it is easier to add preseed to the image during build process. Create &lt;code&gt;preseed.cfg&lt;/code&gt; file with following content:&lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/2964138.js?file=preseed.cfg&quot;&gt;&lt;/script&gt;&lt;p&gt;and add this line to &lt;a href=&quot;https://gist.github.com/2964138#file_config__local.cfg&quot;&gt;&lt;code&gt;config/local&lt;/code&gt;&lt;/a&gt; file:&lt;/p&gt;
&lt;pre&gt;
    PRESEED = preseed.cfg
&lt;/pre&gt;
&lt;h1&gt;Build&lt;/h1&gt;
&lt;p&gt;Now everything is ready and we can build:&lt;/p&gt;
&lt;pre&gt;
    make reallyclean
    fakeroot make build_netboot
&lt;/pre&gt;
&lt;h1&gt;Install&lt;/h1&gt;
&lt;p&gt;Copy all sub-directory &lt;code&gt;dest/netboot/debian-installer/amd64&lt;/code&gt; to Cobbler&amp;#8217;s &lt;code&gt;/var/www/cobbler/ks_mirror/Debian6.0.5/install/debian-installer/amd64&lt;/code&gt; and sync:&lt;/p&gt;
&lt;pre&gt;
   ( cd dest/netboot/debian-installer/amd64 &amp;amp;&amp;amp; \
     tar cf - . | ssh root@cobbler  \
     &quot;(cd /var/www/cobbler/ks_mirror/Debian6.0.5/install/debian-installer/amd64 &amp;amp;&amp;amp; \
       rm -rf * &amp;amp;&amp;amp; tar xf - &amp;amp;&amp;amp; cobbler sync\
      )&quot;                                      
   )
&lt;/pre&gt;

&lt;p&gt;Done.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title> Як перетворити системний диск в case-sensitive</title>
      <link>http://dmytro.github.com//2005/12/15/T10_19_47_09_00.html</link>
      <pubDate>Thu, 15 Dec 2005 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2005/12/15/T10_19_47_09_00</guid>
      <description>&lt;p&gt;&lt;a href=&quot;http://www.macosxhints.com/article.php?story=200502011939237&quot;&gt;З цієї сторінки&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Create a case-sensitive &lt;span class=&quot;caps&quot;&gt;HFS&lt;/span&gt; boot disk&lt;/h1&gt;
&lt;p&gt;&amp;#8216;&amp;#8217;Authored by: jay2 on Tue, Feb 8 &amp;#8217;05 at 02:18PM&amp;#8217;&amp;#8217;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve set up two macs (both running 10.3.x) with case-sensitive boot disks by doing the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;use &lt;a href=&quot;http://www.bombich.com/software/ccc.html&quot;&gt;carbon copy cloner&lt;/a&gt; to make a bootable backup on a firewire disk&lt;/li&gt;
	&lt;li&gt;boot from the backup&lt;/li&gt;
	&lt;li&gt;open a terminal window and incant:&lt;br /&gt;
+ sudo diskutil eraseVolume &amp;#8220;Case-sensitive HFS+&amp;#8221; &amp;#8220;Macintosh HD&amp;#8221; /Volumes/Macintosh HD&lt;br /&gt;
+ (that&amp;#8217;s all on one line)&lt;/li&gt;
	&lt;li&gt;restore from the backup to the newly formatted HD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;cccloner makes it a piece of cake. i did this over a year ago, and have had no problems with case-sensitive hfs+.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Як воювати з Exim'ом</title>
      <link>http://dmytro.github.com//2005/04/11/T10_03_11_09_00.html</link>
      <pubDate>Mon, 11 Apr 2005 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2005/04/11/T10_03_11_09_00</guid>
      <description>&lt;p&gt;Найкращий спосіб для настроювання поштових серверів давно відомий: стерти і встановити sendmail. Але якщо це з якихось причин неможливо &amp;#8212; треба боротися з тим, що є.&lt;/p&gt;
&lt;h2&gt;Exim&lt;/h2&gt;
&lt;p&gt;Так само, як і postfix  розрахований на те, щоб страшенно піклуватися про ресурси комп&amp;#8217;ютера, на якому він працює. Навіть за рахунок того, що доставка пошти може зайняти кілька днів. Зате &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; працює і не пітніє.&lt;/p&gt;
&lt;p&gt;Стандартна конфіґурація exim4 доставляє за раз не більше 10 листів. Симптоми: ви вмикаєте свого fetchmail&amp;#8217;а після відпустки, в черзі кілька тисяч листів і вони починають поступати по 10 штук за кожні 10-20 хвилин. Розрахунок необхідного часу для отримання пошти залишається вправою для читача.&lt;/p&gt;
&lt;p&gt;В журналі повно повідомлень подібних на таке:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;2005-04-11 08:43:58 1DKm5u-0000Nq-U2 no immediate delivery: more than 10 messages received in one connection&lt;/code&gt;&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;i&gt;Підказка&lt;/i&gt; : &lt;di&gt;в Дебіані журнал exim4 знаходиться в &lt;code&gt;/var/log/exim4/mainlog&lt;/code&gt;&lt;/dl&gt;
&lt;p&gt;Вихід: вставити в конфіґурацію exim&amp;#8217;а рядок:&lt;/p&gt;
&lt;pre&gt;
 smtp_accept_queue_per_connection = 0
&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Debian auto login</title>
      <link>http://dmytro.github.com//2004/10/30/debian-auto-login.html</link>
      <pubDate>Sat, 30 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/30/debian-auto-login</guid>
      <description>&lt;p&gt;Це повинно працювати на будь-якому з лінаксів. Випробувано на Дебіані (sarge).&lt;/p&gt;
&lt;h2&gt;Компілюється спеціальна програмка для автоматичного логіну&lt;/h2&gt;
&lt;pre&gt;

    # cat /usr/src/autodk.c 
    int main() {
               execlp( &quot;login&quot;, &quot;login&quot;, &quot;-f&quot;, &quot;dk&quot;, 0);
    }
    
&lt;/pre&gt;
&lt;p&gt;потрібно змінити тільки ім&amp;#8217;я користувача.&lt;/p&gt;
&lt;h3&gt;Компіляція&lt;/h3&gt;
&lt;pre&gt;
    # gcc -o autodk autodk.c
    #  cp autodk /home/dk/
&lt;/pre&gt;
&lt;h2&gt;Зміни до /etc/inittab&lt;/h2&gt;
&lt;pre&gt;
    # grep dk /etc/inittab 
    1:2345:respawn:/sbin/getty -n -l /home/dk/autodk 38400 tty1
&lt;/pre&gt;
&lt;h2&gt;Зміни до .bash_profile&lt;/h2&gt;
&lt;p&gt;Щоб автоматично стартував X там де потрібно (на першому VT) додати:&lt;/p&gt;
&lt;pre&gt;

    # cat ~dk/.bash_profile 
    . . . 
    if [ -z &quot;$DISPLAY&quot; ] &amp;amp;&amp;amp; [ $(tty) == /dev/tty1 ]; then
      startx
    fi
    
    #
&lt;/pre&gt;
&lt;p&gt;Пояснення: запускає автологін програму на 1му вірт. терміналі.&lt;/p&gt;
&lt;h2&gt;Джерела&lt;/h2&gt;
&lt;p&gt;Інформація взята з &lt;a href=&quot;http://www.linuxgazette.com/issue72/chung.html&quot;&gt;ЛінаксГазет&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Покращення швидкодії диска</title>
      <link>http://dmytro.github.com//2004/10/12/T15_57_03_09_00.html</link>
      <pubDate>Tue, 12 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/12/T15_57_03_09_00</guid>
      <description>&lt;p&gt;Це взяте повністю &lt;a href=&quot;http://linux.org.ua/cgi-bin/yabb/YaBB.pl?board=problems;action=display;num=1097532696&quot;&gt;з форуму linux.org.ua&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;автор:&lt;br /&gt;
        Псевдо: iip &lt;br /&gt;
        Ім&amp;#8217;я: iip&lt;br /&gt;
        Розташування: Новачок&lt;br /&gt;
        Дата реєстрації: 17. серпня 2004 17:24&lt;br /&gt;
        Ел. адреса: схована&lt;/p&gt;
&lt;p&gt;Чи є у когось якісь поради щодо покрашання швидкодії лінаксової системи?&lt;/p&gt;
&lt;p&gt;Прошу поділіться тут.&lt;/p&gt;
&lt;p&gt;Я нещодавно підвищив швидкодію свойого жорсткого диску за допомогою команди hdparam. Перш ніж приступити до удосконалення перевірте поточну швидкодію. Введіть у командний рядок з правами адміністратора (su &amp;#8211; root, тощо) наступну команду  &lt;code&gt;/sbin/hdparm -tT /dev/hda&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;hda &amp;#8211; це ваш перший жорсткий диск, hdb &amp;#8211; другий і т.д.&lt;/p&gt;
&lt;p&gt;Після того введіть &lt;code&gt;/sbin/hdparm -c1 -d1 -m16 /dev/hda&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Відтак знов &lt;code&gt;/sbin/hdparm -tT /dev/hda&lt;/code&gt; і порівняйте показники.&lt;/p&gt;
&lt;p&gt;Щоб установки застосовувались при кожному запуску системи вставте ваш hdparm рядок у файл &lt;code&gt;/etc/init.d/boot.local&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Для перевірки режиму &lt;span class=&quot;caps&quot;&gt;DMA&lt;/span&gt;, який використовується у вашій системі можна спочатку виконати hdparm -I /dev/hda, а тоді за допомогою модуля &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;DMA&lt;/span&gt; в Yast (в мене &lt;span class=&quot;caps&quot;&gt;SUSE&lt;/span&gt; 9.1) примусити жорсткий диск використовувати правильний режим &lt;span class=&quot;caps&quot;&gt;DMA&lt;/span&gt; (можливо  udma2 або udma4 &amp;#8211; програма скаже, якщо ваш привід не підтримує певного режиму).&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Заголовок з відступом -- CSS</title>
      <link>http://dmytro.github.com//2004/10/08/T09_42_28_09_00.html</link>
      <pubDate>Fri, 08 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/08/T09_42_28_09_00</guid>
      <description>&lt;p&gt;На &lt;a href=&quot;http://www.acooke.org/andrew/writing/email.html&quot;&gt;http://www.acooke.org/andrew/writing/email.html&lt;/a&gt; заголовки виглядають ось так: &lt;img src=&quot;/images/indent.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; для цих загловків:&lt;/p&gt;
&lt;pre&gt;
    div.indent {
      border: none;
      padding: 0.5em;
      margin-left: -5%;
      float: left;
      padding-right: 5%
    }
&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;/images/indent_html.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Нова мода podcast</title>
      <link>http://dmytro.github.com//2004/10/06/T14_36_10_09_00.html</link>
      <pubDate>Wed, 06 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/06/T14_36_10_09_00</guid>
      <description>&lt;p&gt;Ідея дуже проста &amp;#8212; взяти радіопрограму, записати її в mp3 і засунути в iPod.&lt;/p&gt;
&lt;p&gt;podcast відноситься до того, як це зробити автоматично. Тобто кожного ранку Ви змоєете на іПоді мати свіжий випуск новин з України, чи нічну програму Радіо Люкс:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.engadget.com/entry/5843952395227141/&quot;&gt;як це зробити&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>VPNC на Маку</title>
      <link>http://dmytro.github.com//2004/10/04/T15_23_35_09_00.html</link>
      <pubDate>Mon, 04 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/04/T15_23_35_09_00</guid>
      <description>&lt;p&gt;Стандартний vpnc встановлений з MacPorts не підтримує кількох досить корисних конфігураційних параметрів. Ці параметри були додані Debian&amp;#8217;ом, тому і підтримуються тільки самим Debian&amp;#8217;ом та похідними від нього дистрибутивами.&lt;/p&gt;
&lt;p&gt;Один з таких параметрів Target Networks дозволяє не додавати Default route до мережевого інтерфейсу vpnc &amp;#8211; tun.&lt;/p&gt;
&lt;p&gt;Цей скрипт дозволяє емулювати Target Networks в стандартному vpnc. Конфіґурація скрипта &amp;#8211; пару рядків на початку файла.&lt;/p&gt;
&lt;h1&gt;Скрипт&lt;/h1&gt;
&lt;script src=&quot;https://gist.github.com/3027771.js?file=vpnc.sh&quot;&gt;&lt;/script&gt;</description>
    </item>
    
    <item>
      <title>Debian -- як зняти прапорець -nolisten</title>
      <link>http://dmytro.github.com//2004/10/04/T14_43_09_09_00.html</link>
      <pubDate>Mon, 04 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/04/T14_43_09_09_00</guid>
      <description>&lt;p&gt;Останній дебіан запускає Xserver з прапорцем &lt;code&gt;-nolisten&lt;/code&gt;. Ось де собака зарита:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
 $ ps &amp;#8230;&lt;br /&gt;
   [&amp;#8230;] /usr/X11R6/bin/X [&amp;#8230;] -nolisten tcp [&amp;#8230;]&lt;/p&gt;
&lt;p&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Це підвищує безпеку системи, але одночасно забороняє з&amp;#8217;єднання з віддалених машин до сервера X. Зняти цей прапорець можна в файлі&lt;/p&gt;
&lt;pre&gt;
 $ cat /etc/X11/xinit/xserverrc
 #!/bin/sh
 exec /usr/bin/X11/X -dpi 100 -nolisten tcp
 $ 
&lt;/pre&gt;
&lt;p&gt;Якщо сервер стартує з &lt;span class=&quot;caps&quot;&gt;XDM&lt;/span&gt; то потрібно відредагувати файл &lt;code&gt;/etc/X11/xdm/Xservers&lt;/code&gt;. В ньому так само прибрати прапорець &lt;code&gt;-nolisten&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;

 #:0 local /usr/X11R6/bin/X vt7 -dpi 100 -nolisten tcp :0 local /usr/X11R6/bin/X vt7 -dpi 100 tcp

&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Optical Illusions</title>
      <link>http://dmytro.github.com//2004/10/04/T12_17_09_09_00.html</link>
      <pubDate>Mon, 04 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/04/T12_17_09_09_00</guid>
      <description>&lt;h1&gt;From /. 4 Oct 2004:&lt;/h1&gt;
&lt;p&gt;Science: The Goggles, They Do Nothing&lt;/p&gt;
&lt;p&gt;Posted by michael on Sunday October 03, @07:24PM&lt;/p&gt;
&lt;p&gt;from the do-not-view-while-operating-machinery dept.&lt;/p&gt;
&lt;p&gt;Suchetha writes &amp;#8220;In anticipation of a slow news day i would like to&lt;br /&gt;
direct the Slashdot hordes to&lt;br /&gt;
&lt;a href=&quot;http://www.ritsumei.ac.jp/~akitaoka/index-e.html&quot;&gt;Akiyoshi Kitaoka&amp;#8217;s Optical Illusions page&lt;/a&gt;. The page also has explanations on why/how they occur (in icky &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; format). The page is on a .jp uni server so they &lt;span class=&quot;caps&quot;&gt;SHOULD&lt;/span&gt; be able to handle the herd of rhinos that is ./.&amp;#8221;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Попередження з самої сторінки ілюзій &amp;#8212; &amp;#8220;якщо відчуваєте, що голова крутиться&amp;#8230; тікайте з цієї сторінки&amp;#8221;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Створення NFS експортів у MacOSX з командного рядка</title>
      <link>http://dmytro.github.com//2004/10/04/T10_22_58_09_00.html</link>
      <pubDate>Mon, 04 Oct 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/10/04/T10_22_58_09_00</guid>
      <description>&lt;p&gt;Створення &lt;span class=&quot;caps&quot;&gt;NFS&lt;/span&gt; експорту, щоб його можна було змонтувати з правами &lt;code&gt;rw&lt;/code&gt; для root&amp;#8217;а&lt;/p&gt;
&lt;h1&gt;Як зробити це за допомогою командного рядка.&lt;/h1&gt;
&lt;h2&gt;(1)&lt;/h2&gt;
&lt;pre&gt;
 # niutil -list / /exports
 81       /Volumes/Users
&lt;/pre&gt;
&lt;p&gt;;зауваження: спочатку створюється фіктивна гілка з назвою servername, а потім замінюється на справжню точку експорту. Для того, щоб знати ID  цієї гілки.&lt;/p&gt;
&lt;h2&gt;(2)&lt;/h2&gt;
&lt;pre&gt;
 # niutil -create / exports/servername
 # niutil -list / /exports
 81       /Volumes/Users
 134       servername
&lt;/pre&gt;
&lt;h2&gt;(3)&lt;/h2&gt;
&lt;pre&gt;
 # niutil -insertval / 134 name &quot;/Volumes/NewExport&quot; 0
 # niutil -list / /exports
 81       /Volumes/Users
 134       /Volumes/NewExport servername
 # 
&lt;/pre&gt;
&lt;h2&gt;(4)&lt;/h2&gt;
&lt;pre&gt;
 # niutil -destroyval / 134 name &quot;servername&quot;
 # niutil -list / /exports
 81       /Volumes/Users
 134       /Volumes/NewExport
 # 
&lt;/pre&gt;
&lt;h2&gt;(5)&lt;/h2&gt;
&lt;pre&gt;
 # niutil -createprop / 134 &quot;clients&quot; &quot;myclient.domain&quot;
 # niutil -createprop / 134 &quot;opts&quot; &quot;maproot=0:0&quot;
 # niutil -read / 134
 name: /Volumes/NewExport
 clients: myclient.domain
 opts: maproot=0:0
 # 
&lt;/pre&gt;
&lt;h2&gt;(6)&lt;/h2&gt;
&lt;pre&gt;
 # ps ax | grep mount
  373  ??  Ss     0:00.28 mountd
 # kill -HUP 373 
&lt;/pre&gt;
&lt;h2&gt;Джерела:&lt;/h2&gt;
&lt;ul&gt;
	&lt;li&gt;http://macosx.midata.fi/info-nfsexport/&lt;/li&gt;
	&lt;li&gt;http://deaddog.duch.udel.edu/~frey/darwin/archive/DarwinAndNFS.pdf&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Помилка sendmail</title>
      <link>http://dmytro.github.com//2004/09/24/T12_06_41_09_00.html</link>
      <pubDate>Fri, 24 Sep 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/09/24/T12_06_41_09_00</guid>
      <description>&lt;p&gt;Наступні помилки в Солярисі викликані невірними дозволами на теку /etc.&lt;/p&gt;
&lt;p&gt;&lt;br clear=&#39;all&#39;&gt;
&lt;pre&gt;&lt;br /&gt;
        /etc/mail/sendmail.cf: line 77: fileclass: cannot open&lt;br /&gt;
        &amp;#8216;/etc/mail/local-host-names&amp;#8217;: Group writable directory&lt;br /&gt;
        /etc/mail/sendmail.cf: line 493: fileclass: cannot open&lt;br /&gt;
        &amp;#8216;/etc/mail/trusted-users&amp;#8217;: Group writable directory&lt;br /&gt;
&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Виправлення досить просте: &lt;code&gt;chmod g-w /etc&lt;/code&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>20 years ago / 20 років тому...</title>
      <link>http://dmytro.github.com//2004/02/20/20_years_ago.html</link>
      <pubDate>Fri, 20 Feb 2004 00:00:00 +0900</pubDate>
      <author>dmytro.kovalov@gmail.com (Dmytro Kovalov)</author>
      <guid>http://dmytro.github.com//2004/02/20/20_years_ago</guid>
      <description>&lt;p&gt;The Macintosh uses an experimental pointing device called a &amp;#8216;mouse.&amp;#8217; There is no evidence that people want to use these things.&lt;/p&gt;
&lt;i&gt;John C. Dvorak, SF Examiner, Feb. 1984.&lt;/i&gt;</description>
    </item>
    

  </channel> 
</rss>

