<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mushycode</title>
    <description>My thoughtsdump and playground
</description>
    <link>https://mushycode.in/</link>
    <atom:link href="https://mushycode.in/sitemap.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 21 Jul 2024 04:51:19 +0000</pubDate>
    <lastBuildDate>Sun, 21 Jul 2024 04:51:19 +0000</lastBuildDate>
    <generator>Jekyll v3.9.5</generator>
    
      <item>
        <title>Podman and Colima as docker desktop alternatives for enterprise users</title>
        <description>&lt;h1 id=&quot;docker-desktop-alternatives-for-enterprise-users&quot;&gt;Docker Desktop Alternatives for Enterprise Users&lt;/h1&gt;

&lt;p&gt;Docker has changed its &lt;a href=&quot;https://www.docker.com/pricing/&quot;&gt;Service Agreement&lt;/a&gt; and requires a paid subscription for Docker Desktop. It is a popular tool used by many developers to manage containers on their Mac. However, some users may want to explore alternatives to Docker Desktop / Docker for various reasons, such as performance issues or the desire for daemonless docker. Two possible alternatives to Docker Desktop on a Mac are &lt;a href=&quot;https://podman.io/&quot;&gt;Podman&lt;/a&gt; and &lt;a href=&quot;https://github.com/abiosoft/colima&quot;&gt;Colima&lt;/a&gt;. In this blog, I just wanted to quickly document my experience on try out these two alternatives as well as the pros and cons of each.&lt;/p&gt;

&lt;h2 id=&quot;replacing-docker-desktop-with-podman-on-mac&quot;&gt;Replacing Docker Desktop with Podman on Mac&lt;/h2&gt;

&lt;p&gt;Podman is a container management tool that allows users to manage containers without requiring a daemon to be running in the background. It is an open-source project developed by Red Hat and provides a CLI that is compatible with Docker.&lt;/p&gt;

&lt;p&gt;Install Podman: Podman can be installed on a Mac using Homebrew. Open a terminal window and enter the following commands:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;podman

brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;podman-completion&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will install Podman and its completion script.&lt;/p&gt;

&lt;p&gt;Start using Podman: Once Podman is installed, you can start using it to manage your containers. To run a container, use the podman run command. For example, to run a simple hello-world container, enter the following command in the terminal:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;podman run hello-world&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;pros-and-cons-of-podman&quot;&gt;Pros and Cons of Podman&lt;/h2&gt;

&lt;h3 id=&quot;pros&quot;&gt;Pros:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Podman does not require a daemon to be running in the background, which can improve performance and security.&lt;/li&gt;
  &lt;li&gt;Podman provides a Docker-compatible CLI, making it easy to switch from Docker to Podman.&lt;/li&gt;
  &lt;li&gt;Podman supports rootless containers, which allows non-root users to run containers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons&quot;&gt;Cons:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Podman is not as widely used as Docker, so finding support or tutorials may be more difficult.&lt;/li&gt;
  &lt;li&gt;Podman does not currently support Docker Compose, although this may change in the future.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note: I had issues with volume mounting in podman, but looks like passing the mount to podman machine during its creation fixes it.
For ex,&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;podman machine init &lt;span class=&quot;nt&quot;&gt;--disk-size&lt;/span&gt; 20 &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\$&lt;/span&gt;HOME:&lt;span class=&quot;nv&quot;&gt;$HOME&lt;/span&gt;

podman machine start&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;replacing-docker-desktop-with-colima-on-mac&quot;&gt;Replacing Docker Desktop with Colima on Mac&lt;/h2&gt;

&lt;p&gt;Colima is a Docker and Kubernetes development environment for Mac. It is built on top of macOS Hypervisor framework and provides a lightweight, native experience for managing containers.&lt;/p&gt;

&lt;p&gt;To replace Docker Desktop with Colima on a Mac, follow these steps:&lt;/p&gt;

&lt;p&gt;Install Colima: Colima can be downloaded from the official website. Once downloaded, open the DMG file and drag the Colima app to the Applications folder.&lt;/p&gt;

&lt;p&gt;Start using Colima: Once Colima is installed, open the app and follow the setup instructions. You can then start using Colima to manage your containers.&lt;/p&gt;

&lt;h2 id=&quot;pros-and-cons-of-colima&quot;&gt;Pros and Cons of Colima&lt;/h2&gt;

&lt;h3 id=&quot;pros-1&quot;&gt;Pros:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Colima provides a lightweight, native experience for managing containers on a Mac.&lt;/li&gt;
  &lt;li&gt;Colima supports Docker Compose and Kubernetes, making it a versatile tool for container management.&lt;/li&gt;
  &lt;li&gt;Colima provides a web-based interface for managing containers, which can be more user-friendly than a CLI.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cons-1&quot;&gt;Cons:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Colima is a relatively new tool and may have bugs or compatibility issues.
C- olima is not as widely used as Docker, so finding support or tutorials may be more difficult.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Replacing Docker Desktop with Podman or Colima on a Mac is relatively easy, and both tools offer certain pros and cons. Podman is a lightweight tool that provides a Docker-compatible CLI, while Colima provides a native, web-based interface for managing containers. Ultimately, the choice of which tool to use depends on the user.&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Mar 2023 00:00:00 +0000</pubDate>
        <link>https://mushycode.in/docker-desktop-alternative-podman-colima.html</link>
        <guid isPermaLink="true">https://mushycode.in/docker-desktop-alternative-podman-colima.html</guid>
        
        <category>docker</category>
        
        <category>docker-desktop</category>
        
        <category>mac</category>
        
        <category>colima</category>
        
        <category>podman</category>
        
        
        <category>docker</category>
        
        <category>docker-desktop</category>
        
        <category>mac</category>
        
      </item>
    
      <item>
        <title>Lessons from Sectigo's Expired Certificates</title>
        <description>&lt;h2 id=&quot;lessons-from-sectigos-expired-certificates---why-it-is-important-to-validate-ssl-certificate-chain-and-not-just-root-ssl-certificate-in-monitoring-systems&quot;&gt;Lessons from Sectigo’s Expired Certificates - Why it is important to validate SSL certificate chain and not just root SSL certificate in monitoring systems&lt;/h2&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;how-it-all-started-today&quot;&gt;How it all started today?&lt;/h3&gt;
&lt;p&gt;Today we noticed that in some of our applications connection to our internal API’s are failing with the following error messages -&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;RestClient::SSLCertificateNotVerified (SSL_connect returned=1 errno=0 state=error: certificate verify failed)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When we checked the nginx logs of the API’s we saw the following error -&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;SSL_shutdown() failed (SSL: error:140E0197:SSL routines:SSL_shutdown:shutdown while in init) while SSL handshaking
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;API’s health check from browser did not show any issue, all seemed fine. Infact, the SSL certificate was not expiring before 2021. So what was causing this issue? Upon further investigation it was found that one of the intermediate certificate in the certificate chain has expired!
Sectigo’s External CA root expired and thus our certifactes had issues.&lt;/p&gt;

&lt;h3 id=&quot;how-did-we-fix-it&quot;&gt;How did we fix it?&lt;/h3&gt;
&lt;p&gt;The fix was to update our full certificate file with the new roots. In our case, it looked like the following -&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. Subject CN: *.ourdomain.com &amp;gt; Issuer CN: Sectigo RSA Domain Validation Secure Server CA
2. Subject CN: Sectigo RSA Domain Validation Secure Server CA &amp;gt; Issuer CN: USERTrust RSA Certification Authority
3. Subject CN: USERTrust RSA Certification Authority &amp;gt; Issuer CN: AddTrust External CA Root
4. Subject CN: AddTrust External CA Root &amp;gt; Issuer CN: AddTrust External CA Root
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We updated the new UserTrust certs for Sectigo from &lt;a href=&quot;https://support.sectigo.com/articles/Knowledge/Sectigo-AddTrust-External-CA-Root-Expiring-May-30-2020&quot;&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The modern root certificates are availble under the heading &lt;strong&gt;USERTrust RSA Certification Authority&lt;/strong&gt;. A couple of sections below the cross certificates are also availble.&lt;/p&gt;

&lt;p&gt;The certificates need not be re-issued and can be updated with these new ones. In our case 3 and 4 in the full chain were replaced.&lt;/p&gt;

&lt;p&gt;Hope this helps someone. Let me know in case there is some correction.&lt;/p&gt;

</description>
        <pubDate>Sat, 30 May 2020 20:43:52 +0000</pubDate>
        <link>https://mushycode.in/fix-sectigo-expired-cert.html</link>
        <guid isPermaLink="true">https://mushycode.in/fix-sectigo-expired-cert.html</guid>
        
        <category>ssl</category>
        
        <category>issues</category>
        
        <category>sectigo</category>
        
        <category>certificates</category>
        
        <category>ssl-expiry</category>
        
        
        <category>ssl</category>
        
      </item>
    
      <item>
        <title>Commonly used Elasticsearch REST APIs at work</title>
        <description>&lt;h2 id=&quot;helpful-elasticsearch-apis&quot;&gt;Helpful Elasticsearch APIs&lt;/h2&gt;

&lt;p&gt;This is a simple post listing the Elasticsearch rest APIs that I use most at work.&lt;/p&gt;

&lt;h3 id=&quot;list-all-indices&quot;&gt;List all indices&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/_cat/indices&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;list-all-shards&quot;&gt;List all shards&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/_cat/shards&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;list-all-elasticserach-nodes&quot;&gt;List all elasticserach nodes&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/_nodes?pretty&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/_cluster/allocation/explain?pretty&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'localhost:9200/_cat/allocation?v'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-XPOST&lt;/span&gt; localhost:9200/_cluster/reroute?retry_failed&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST localhost:9200/_reindex &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'cache-control: no-cache'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'content-type: application/json'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;source&quot;: {
    &quot;index&quot;: &quot;&amp;lt;&amp;lt;index_old_ones_with_data&amp;gt;&amp;gt;&quot;,
    &quot;query&quot;: {
        &quot;match_all&quot;: {}
    }
  },
  &quot;dest&quot;: {
    &quot;index&quot;: &quot;&amp;lt;&amp;lt;new_index_with_new_mapping&amp;gt;&amp;gt;&quot;
  }
}'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST localhost:9200/_reindex &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'cache-control: no-cache'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'content-type: application/json'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'{
  &quot;source&quot;: {
    &quot;remote&quot;: {
      &quot;host&quot;: &quot;http://&amp;lt;some-ip&amp;gt;:9200&quot;
    },
    &quot;index&quot;: &quot;&amp;lt;&amp;lt;index_old_ones_with_data&amp;gt;&amp;gt;&quot;,
    &quot;query&quot;: {
        &quot;match_all&quot;: {}
    }
  },
  &quot;dest&quot;: {
    &quot;index&quot;: &quot;&amp;lt;&amp;lt;new_index_with_new_mapping&amp;gt;&amp;gt;&quot;
  }
}'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/&amp;lt;index_name&amp;gt;/_search?pretty&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'
{
  &quot;query&quot;: {
    &quot;match&quot;: {
      &quot;&amp;lt;field&amp;gt;&quot;: &quot;&amp;lt;field-value&amp;gt;&quot;
    }
  }
}
'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;curl &lt;span class=&quot;nt&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;s2&quot;&gt;&quot;localhost:9200/&amp;lt;index_name&amp;gt;/_delete_by_query?pretty&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'
{
  &quot;query&quot;: {
    &quot;match&quot;: {
      &quot;&amp;lt;field&amp;gt;&quot;: &quot;&amp;lt;field-value&amp;gt;&quot;
    }
  }
}
'&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;PS: I will add description for each soon&lt;/p&gt;
</description>
        <pubDate>Wed, 13 May 2020 13:13:55 +0000</pubDate>
        <link>https://mushycode.in/useful-elasticsearch-rest-apis.html</link>
        <guid isPermaLink="true">https://mushycode.in/useful-elasticsearch-rest-apis.html</guid>
        
        <category>elasticsearch</category>
        
        <category>rest-api</category>
        
        
        <category>elasticsearch</category>
        
      </item>
    
      <item>
        <title>Understanding docker layers and overlay filesystem</title>
        <description>&lt;h2 id=&quot;what-are-docker-layers-and-overlay-filesystems&quot;&gt;What are docker layers and overlay filesystems&lt;/h2&gt;
&lt;p&gt;A docker image consists of layers. Each layer is an instruction in the Dockerfile. A container is an image with a writable(or readable) layer or top of other read only layers. This is where an overlayfs comes in to picture.
This was one of the things that I wanted to understand better - What exactly is an overlay file system and how is docker using it.
From archlinux wiki definition
“Overlayfs allows one, usually read-write, directory tree to be overlaid onto another, read-only directory tree. All modifications go to the upper, writable layer.”&lt;/p&gt;

&lt;p&gt;An apt example is a linux live CD.&lt;/p&gt;

&lt;p&gt;Lets get down to how this overlay file system works&lt;/p&gt;

&lt;h3 id=&quot;overlays-and-docker&quot;&gt;Overlays and docker&lt;/h3&gt;

&lt;p&gt;It consists of three layers for the sake of simplicity.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Lower Read Only Layer&lt;/li&gt;
  &lt;li&gt;Upper Layer that allows read and write&lt;/li&gt;
  &lt;li&gt;The Overlay layer itself that gives the user entire view of the filesystem and from where user actually reads a file or writes to them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;lower-layer&quot;&gt;Lower Layer&lt;/h4&gt;
&lt;p&gt;The read only layer where base files of the filesystem are stored. It can be visualized as the base image of our docker image or root of a live CD example.&lt;/p&gt;

&lt;h4 id=&quot;upper-layer&quot;&gt;Upper Layer&lt;/h4&gt;
&lt;p&gt;Any changes made in the overlay layer gets stored in the upper layer. Whenever a process reads a file from the overlay layer, it is checked in upper layer first, if not available it is read from the lower layer.&lt;/p&gt;

&lt;h4 id=&quot;overlay&quot;&gt;Overlay&lt;/h4&gt;
&lt;p&gt;This is the consolidated or union view of lower and upper layers and where the user works on. Whenever any changes are made to a file, overlay layer presents the union of upper and lower layers such that files in upper layer supersede the ones in lower layer.&lt;/p&gt;

&lt;p&gt;When objects with the same name exist in both directory trees of upper and lower layers, then their treatment depends on the object type:&lt;/p&gt;

&lt;p&gt;File: We see the file in the upper layer, and the file in the lower layer is hidden.&lt;/p&gt;

&lt;p&gt;Directory: content of both upper and lower layers of the directory tree is combined and shown in the overlay&lt;/p&gt;

&lt;h4 id=&quot;copy-on-write&quot;&gt;Copy-on-Write&lt;/h4&gt;
&lt;p&gt;Whenever a file already present in lower layer is modified, the file is first copied over to the upper layer and then the modifications are made here.&lt;/p&gt;

&lt;h4 id=&quot;overlay-in-action&quot;&gt;Overlay in action&lt;/h4&gt;

&lt;p&gt;Lets create directories&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;lower upper merged workdir
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I am in lower layer&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; lower/lower.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I am in upper layer&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; upper/upper.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I am common file lower layer&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; lower/common.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I am common file upper layer&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; upper/common.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; overlay overlay &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lowerdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/lower,upperdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/upper,workdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/workdir /root/merged
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;merged/
common.txt  lower.txt  upper.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;merged/common.txt 
I am common file upper layer
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;lower/
common.txt  lower.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;upper/
common.txt  upper.txt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The lower layer can be read-only and an overlay itself, while the upper layer is normally writeable. In order to create an overlay of two directories, dir1 and dir2, we can use the following mount command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;mount &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; overlay overlay &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;lowerdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/lower2:/root/lower1,upperdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/upper,workdir&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/root/workdir /root/merged&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;while specifying multiple lower layers, they are separated by a :, with the rightmost lower directory on the bottom, and the leftmost lower directory on the top of the overlay.&lt;/p&gt;

&lt;h4 id=&quot;new-file-creation-in-overlay&quot;&gt;New file creation in overlay&lt;/h4&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;I am the new file on the block&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; merged/new.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;merged/
common.txt  lower.txt  new.txt  upper.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;upper/
common.txt  new.txt  upper.txt
root@dd4a4d50aefc:~# &lt;span class=&quot;nb&quot;&gt;ls &lt;/span&gt;lower/
common.txt  lower.txt&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;References&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;https://docs.docker.com/storage/storagedriver/#images-and-layers&lt;/li&gt;
  &lt;li&gt;https://wiki.archlinux.org/index.php/Overlay_filesystem&lt;/li&gt;
  &lt;li&gt;https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 19 Nov 2019 12:47:46 +0000</pubDate>
        <link>https://mushycode.in/docker-layers-and-overlay-fs.html</link>
        <guid isPermaLink="true">https://mushycode.in/docker-layers-and-overlay-fs.html</guid>
        
        <category>docker</category>
        
        <category>docker-layers</category>
        
        <category>overlay</category>
        
        
        <category>docker</category>
        
      </item>
    
      <item>
        <title>How to write safe shell scripts</title>
        <description>&lt;h2 id=&quot;good-practices-in-bash-scripts&quot;&gt;Good Practices in bash scripts&lt;/h2&gt;

&lt;h3 id=&quot;shebang-&quot;&gt;Shebang (#!)&lt;/h3&gt;

&lt;p&gt;It is called a shebang or a “bang” line. It is nothing but the absolute path to the Bash interpreter. It consists of a number sign and an exclamation point character (#!), followed by the full path to the interpreter such as /bin/bash. All scripts under Linux execute using the interpreter specified on a first line.
This ensures that the correct interpreter will be used to interpret the script, even if it is executed under another shell.&lt;/p&gt;

&lt;h3 id=&quot;set--e&quot;&gt;set -e&lt;/h3&gt;

&lt;p&gt;this will make the shell script exit as soon as any line in the bash script fails.
for example, a shell file like below will execute every line
&lt;script src=&quot;https://gist.github.com/501d903a4db01b5bcbf4e59e7ecae7c2.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./set_e_without.sh 
&lt;span class=&quot;nb&quot;&gt;true
true
false
true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After adding set -e, it will stop executing after the line that fails, in this case the one that returns false.
&lt;script src=&quot;https://gist.github.com/9d841d3cc79224faf16f8fc602799372.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./with_set_e.sh 
&lt;span class=&quot;nb&quot;&gt;true
true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;ignore-failure-in-scripts&quot;&gt;Ignore failure in scripts&lt;/h3&gt;
&lt;p&gt;if we don’t want the script to fail after certain failing statements, we can append these certain statements with || true.&lt;/p&gt;

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

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./with_set_e_and_ignore_fail.sh           
&lt;span class=&quot;nb&quot;&gt;true
true
&lt;/span&gt;failing foo was ignored
&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;set--x&quot;&gt;set -x&lt;/h3&gt;

&lt;p&gt;this will make the shell print each line before execution. Combining this with previous set statement and same example, it will look like
&lt;script src=&quot;https://gist.github.com/a9c92e43f02fd4c65514bb63fb05dce4.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./with_set_x.sh           
++ &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
++ &lt;span class=&quot;nb&quot;&gt;echo true
true&lt;/span&gt;
++ &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;
++ &lt;span class=&quot;nb&quot;&gt;echo true
true&lt;/span&gt;
++ &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;set--u&quot;&gt;set -u&lt;/h3&gt;

&lt;p&gt;The following example has variable &lt;em&gt;b&lt;/em&gt; which is not set. The run of the script will be successful.
&lt;script src=&quot;https://gist.github.com/a9b2414088f39537cbd6e168e9e716f6.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./without_set_u.sh 
++ &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
++ &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;0
0
++ &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;0
0
++ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt;

++ &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;0
0&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;But adding &lt;em&gt;-u&lt;/em&gt; to the same script will force bash to treat unset variables as an error and exit immediately.
&lt;script src=&quot;https://gist.github.com/ca24e436660a986cbd58d9b22f113ce2.js&quot;&gt; &lt;/script&gt;&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./with_set_u.sh 
++ &lt;span class=&quot;nv&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
++ &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;0
0
++ &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;0
0
./with_set_u.sh: line 5: b: unbound variable&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;set--o-pipefail&quot;&gt;set -o pipefail&lt;/h3&gt;

&lt;p&gt;bash usually looks at the exit code of the last command in a pipeline. This can cause a problem for -e option as it will only consider the leftmost command’s exit code in a pipeline.
This particular option sets the exit code of pipeline commands to that of the rightmost command to exit with a non-zero status or 0 if all exit successfully.&lt;/p&gt;

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

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./without_pipefail.sh 
./test.sh: line 3: a: unbound variable
++ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'pipe chain failed'&lt;/span&gt;
pipe chain failed
++ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'but I execute'&lt;/span&gt;
but I execute&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

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

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./with_pipefail.sh 
./test.sh: line 3: a: unbound variable
++ &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'pipe chain failed'&lt;/span&gt;
pipe chain failed

arun@home:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$?&lt;/span&gt;
1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;the echo $? is a special variable in bash that shows the exit code of last run command.&lt;/p&gt;

</description>
        <pubDate>Wed, 13 Nov 2019 15:52:57 +0000</pubDate>
        <link>https://mushycode.in/write-safe-shell-scripts.html</link>
        <guid isPermaLink="true">https://mushycode.in/write-safe-shell-scripts.html</guid>
        
        <category>script</category>
        
        <category>bash</category>
        
        <category>best-practices</category>
        
        
        <category>script</category>
        
        <category>bash</category>
        
      </item>
    
      <item>
        <title>How to remove file in linux using regex</title>
        <description>&lt;h2 id=&quot;deleting-older-files-within-a-date-range&quot;&gt;Deleting older files within a date range&lt;/h2&gt;

&lt;p&gt;Generally compressed log files created by utilities contain a date in the filename.
For cleaning such accumulated compressed files we can use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm&lt;/code&gt; command with regex.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls

&lt;/span&gt;2013-12-23-nginx.tar.gz                2016-04-29-nginx.tar.gz
2013-12-24-nginx.tar.gz                2016-05-21-nginx.tar.gz
2016-04-19-nginx.tar.gz                2016-05-22-nginx.tar.gz
2016-04-20-nginx.tar.gz                2016-05-23-nginx.tar.gz
2016-04-21-nginx.tar.gz                2016-05-24-nginx.tar.gz
2016-04-22-nginx.tar.gz                2016-05-25-nginx.tar.gz
2016-04-23-nginx.tar.gz                2016-06-11-nginx.tar.gz
2016-04-24-nginx.tar.gz                2016-06-12-nginx.tar.gz
2016-04-25-nginx.tar.gz                2016-06-13-nginx.tar.gz
2016-04-26-nginx.tar.gz                2016-12-24-nginx.tar.gz
2016-04-27-nginx.tar.gz                2019-07-20-nginx.tar.gz
2016-04-28-nginx.tar.gz


&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rm &lt;/span&gt;201[3-6]&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Fri, 19 Jul 2019 23:20:00 +0000</pubDate>
        <link>https://mushycode.in/how-to-remove-files-using-regex.html</link>
        <guid isPermaLink="true">https://mushycode.in/how-to-remove-files-using-regex.html</guid>
        
        <category>linux</category>
        
        <category>bash</category>
        
        <category>script</category>
        
        <category>regex</category>
        
        
        <category>regex</category>
        
      </item>
    
  </channel>
</rss>
