<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://theikalman.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://theikalman.github.io/" rel="alternate" type="text/html" /><updated>2026-03-25T23:22:58+00:00</updated><id>https://theikalman.github.io/feed.xml</id><title type="html">AjiYakin</title><subtitle>Blogging, photography, etc. Around AjiYakin thought.</subtitle><author><name>AjiYakin</name></author><entry><title type="html">My First Custom Split Keyboard with Raspberry Pi Pico</title><link href="https://theikalman.github.io/my-first-custom-split-keyboard" rel="alternate" type="text/html" title="My First Custom Split Keyboard with Raspberry Pi Pico" /><published>2025-09-07T14:00:00+00:00</published><updated>2025-09-07T14:00:00+00:00</updated><id>https://theikalman.github.io/my-first-custom-split-keyboard</id><content type="html" xml:base="https://theikalman.github.io/my-first-custom-split-keyboard"><![CDATA[<p>A few months ago, I started experiencing wrist pain — specifically in my left
hand — a clear sign of RSI (Repetitive Strain Injury). As a software engineer,
I type all day, and I realized I couldn’t ignore the discomfort any longer.</p>

<p>So I decided to take matters into my own hands — literally — by building a
custom split keyboard that better fit my ergonomic needs. The result? Not only
did I learn a lot through the process, but my RSI pain is now completely gone
after just two months of daily use.</p>

<hr />

<h2 id="cardboard-and-printed-layout">Cardboard and Printed Layout</h2>

<p>Before I jump and build the real keyboard, I wanted to get feel of split
keyboard first, and since I don’t have access to it yet, I decided to just
print it on the paper and just try to lay my hand there.</p>

<p>Next, after I get the feel on what kind of layout I wanted, I started with a
simple prototype. I printed out a layout based on an ortholinear QWERTY design,
lay it on top of cardboard and then started to make a hole for the MX-style
switches. This early test helped me understand how my fingers would travel
across the keys and how much spacing felt natural.</p>

<p>I didn’t want to switch to something like Dvorak or Colemak because sometimes I
still wanted to be able to use my laptop built-in keyboard. So, I wanted to
keep the familiar QWERTY layout but remove the traditional staggered rows —
which I’ve come to realize aren’t really ergonomic at all. Ortholinear was the
perfect middle ground: it’s cleaner, easier on the hands, and still intuitive.</p>

<p><img src="/postimages/IMG_20250326_122404-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250326_122321-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250326_150536-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" /></p>

<hr />

<h2 id="building-the-case-with-a-cnc-machine">Building the Case with a CNC Machine</h2>

<p>Because I don’t have a 3D printer, I took a different route. My family happens
to have a CNC machine that is used to use for making their logo from acrylic
for their hijab business, so I designed the keyboard case as a sandwich-style
build with that.</p>

<p><img src="/postimages/IMG_20250327_130202-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250327_130445-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250327_135606-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250330_103405-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250330_122529-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250330_122540-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250330_124242-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250404_081853-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250404_081924-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250404_082008-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250409_234659-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" /></p>

<hr />

<h2 id="powered-by-raspberry-pi-pico-and-kmk-firmware">Powered by Raspberry Pi Pico and KMK Firmware</h2>

<p>For the brains of the keyboard, I chose the <em>Raspberry Pi Pico</em>, this is
because its cheaper compared to the other such as <em>pro micro</em> or <em>nice!nano</em> —
one for each half. I’m running KMK firmware, a Python-based firmware built for
custom keyboards. KMK is especially nice if you’re already comfortable with
Python; it makes defining layers, combos, and key behavior straightforward.</p>

<p><img src="/postimages/IMG_20250411_094339-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250411_094348-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250417_081701-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" /></p>

<hr />

<h2 id="2-months-in-no-more-rsi">2 Months In: No More RSI</h2>

<p>After two months of using this keyboard as my daily driver, the results are
clear: my wrist pain is gone. The split design lets me keep my shoulders
relaxed and wrists straight, while the ortholinear layout reduces finger
movement strain. It’s a night-and-day difference from standard keyboards for
me.</p>

<p><img src="/postimages/IMG_20250423_151918-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" /></p>

<hr />

<h2 id="whats-next-making-it-more-portable">What’s Next: Making It More Portable</h2>

<p>Right now, the keyboard uses MX-style switches, which are pretty bulky. For my
next build, I’m exploring low-profile switch options to make a more portable
version — something I can toss into a backpack and use on the go. I’m also
considering integrating a custom cable solution or going wireless if power
efficiency allows.</p>

<p><img src="/postimages/IMG_20250417_134233-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" />
<img src="/postimages/IMG_20250417_134240-small.jpg" alt="My First Custom Keyboard with RaspBerry Pi" /></p>

<hr />

<h2 id="final-thoughts">Final Thoughts</h2>

<p>This project started as a way to deal with wrist pain, but it ended up becoming
one of the most satisfying and useful DIY builds I’ve ever done. I combined
software, hardware, and a bit of CNC machining to create something uniquely
mine — and it solved a real problem.</p>

<p>If you’ve ever struggled with RSI or just want to try something ergonomic and
custom, I highly recommend diving into the world of DIY keyboards. You don’t
need a 3D printer, and you don’t need to switch to a weird layout — just start
simple and iterate. Even there’s a lot of pre-made, read-to-build custom split
keyboard that is available in some eCommerce website, you probably wanted to go
that route if you prefer to just build it.</p>]]></content><author><name>AjiYakin</name></author><category term="Dev" /><category term="Documentation" /><category term="Development" /><category term="Documentation" /><summary type="html"><![CDATA[A few months ago, I started experiencing wrist pain — specifically in my left hand — a clear sign of RSI (Repetitive Strain Injury). As a software engineer, I type all day, and I realized I couldn’t ignore the discomfort any longer.]]></summary></entry><entry><title type="html">Debugging PHP App in NeoVim with Launch Configuration</title><link href="https://theikalman.github.io/debugging-php-app-in-neovim" rel="alternate" type="text/html" title="Debugging PHP App in NeoVim with Launch Configuration" /><published>2025-05-06T06:00:00+00:00</published><updated>2025-05-06T06:00:00+00:00</updated><id>https://theikalman.github.io/debugging-php-app-in-neovim</id><content type="html" xml:base="https://theikalman.github.io/debugging-php-app-in-neovim"><![CDATA[<p>Sometimes I need to debug PHP code in two different situations: a CLI (command-line) app and a web server app. While the way to run each one is slightly different, the steps are subtle, and I often forget the correct order for each case.</p>

<h3 id="neovim-plugin">NeoVim Plugin</h3>
<ul>
  <li><code class="language-plaintext highlighter-rouge">mfussenegger/nvim-dap</code></li>
  <li><code class="language-plaintext highlighter-rouge">kristijanhusak/vim-dadbod-ui</code></li>
</ul>

<h3 id="project-directory-structure">Project Directory Structure</h3>
<p>Assuming we have this project directory structure:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>src
└── App.php -- This is the entry point for CLI app
index.php   -- This is the entry point for Server app
composer.json
flake.nix   -- Nix flake file (NixOS)
.user.ini   -- PHP ini configuration
.vscode
└── launch.json -- Launch configuration
</code></pre></div></div>

<p>I am currently using Nix package manager to setup environment for each project that I have. With nix it is much more convenient to setup PHP environment since I can enable and include necessary PHP extension that I need to have, in this case I need to have xdebug extension.</p>

<p><code class="language-plaintext highlighter-rouge">flake.nix</code>:</p>
<div class="language-nix highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span>
  <span class="nv">description</span> <span class="o">=</span> <span class="s2">"debugphp"</span><span class="p">;</span>

  <span class="nv">inputs</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nv">nixpkgs</span><span class="o">.</span><span class="nv">url</span> <span class="o">=</span> <span class="s2">"github:NixOS/nixpkgs/nixos-unstable"</span><span class="p">;</span>
    <span class="nv">nix-shell</span><span class="o">.</span><span class="nv">url</span> <span class="o">=</span> <span class="s2">"github:loophp/nix-shell"</span><span class="p">;</span>
    <span class="nv">systems</span><span class="o">.</span><span class="nv">url</span> <span class="o">=</span> <span class="s2">"github:nix-systems/default"</span><span class="p">;</span>
  <span class="p">};</span>

  <span class="nv">outputs</span> <span class="o">=</span>
    <span class="nv">inputs</span><span class="o">@</span><span class="p">{</span>
      <span class="nv">self</span><span class="p">,</span>
      <span class="nv">flake-parts</span><span class="p">,</span>
      <span class="nv">systems</span><span class="p">,</span>
      <span class="o">...</span>
    <span class="p">}:</span>
    <span class="nv">flake-parts</span><span class="o">.</span><span class="nv">lib</span><span class="o">.</span><span class="nv">mkFlake</span> <span class="p">{</span> <span class="kn">inherit</span> <span class="nv">inputs</span><span class="p">;</span> <span class="p">}</span> <span class="p">{</span>
      <span class="nv">systems</span> <span class="o">=</span> <span class="kr">import</span> <span class="nv">systems</span><span class="p">;</span>

      <span class="nv">perSystem</span> <span class="o">=</span>
        <span class="p">{</span>
          <span class="nv">config</span><span class="p">,</span>
          <span class="nv">self</span><span class="err">'</span><span class="p">,</span>
          <span class="nv">inputs</span><span class="err">'</span><span class="p">,</span>
          <span class="nv">pkgs</span><span class="p">,</span>
          <span class="nv">system</span><span class="p">,</span>
          <span class="nv">lib</span><span class="p">,</span>
          <span class="o">...</span>
        <span class="p">}:</span>
        <span class="kd">let</span>
          <span class="nv">php</span> <span class="o">=</span> <span class="nv">pkgs</span><span class="o">.</span><span class="nv">api</span><span class="o">.</span><span class="nv">buildPhpFromComposer</span> <span class="p">{</span>
            <span class="nv">src</span> <span class="o">=</span> <span class="nv">inputs</span><span class="o">.</span><span class="nv">self</span><span class="p">;</span>
            <span class="nv">php</span> <span class="o">=</span> <span class="nv">pkgs</span><span class="o">.</span><span class="nv">php83</span><span class="p">;</span> <span class="c"># Change to php56, php70, ..., php81, php82, php83 etc.</span>
          <span class="p">};</span>
        <span class="kn">in</span>
        <span class="p">{</span>
          <span class="nv">_module</span><span class="o">.</span><span class="nv">args</span><span class="o">.</span><span class="nv">pkgs</span> <span class="o">=</span> <span class="kr">import</span> <span class="nv">self</span><span class="o">.</span><span class="nv">inputs</span><span class="o">.</span><span class="nv">nixpkgs</span> <span class="p">{</span>
            <span class="kn">inherit</span> <span class="nv">system</span><span class="p">;</span>
            <span class="nv">overlays</span> <span class="o">=</span> <span class="p">[</span> <span class="nv">inputs</span><span class="o">.</span><span class="nv">nix-shell</span><span class="o">.</span><span class="nv">overlays</span><span class="o">.</span><span class="nv">default</span> <span class="p">];</span>
            <span class="nv">config</span><span class="o">.</span><span class="nv">allowUnfree</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
          <span class="p">};</span>

          <span class="nv">devShells</span><span class="o">.</span><span class="nv">default</span> <span class="o">=</span> <span class="nv">pkgs</span><span class="o">.</span><span class="nv">mkShellNoCC</span> <span class="p">{</span>
            <span class="nv">name</span> <span class="o">=</span> <span class="s2">"php-devshell"</span><span class="p">;</span>
            <span class="nv">buildInputs</span> <span class="o">=</span> <span class="p">[</span>
              <span class="nv">php</span>
              <span class="nv">php</span><span class="o">.</span><span class="nv">packages</span><span class="o">.</span><span class="nv">composer</span>
              <span class="nv">pkgs</span><span class="o">.</span><span class="nv">phpunit</span>
            <span class="p">];</span>
          <span class="p">};</span>

          <span class="nv">apps</span> <span class="o">=</span> <span class="p">{</span>
            <span class="c"># nix run .#composer -- --version</span>
            <span class="nv">composer</span> <span class="o">=</span> <span class="p">{</span>
              <span class="nv">type</span> <span class="o">=</span> <span class="s2">"app"</span><span class="p">;</span>
              <span class="nv">program</span> <span class="o">=</span> <span class="nv">lib</span><span class="o">.</span><span class="nv">getExe</span> <span class="p">(</span>
                <span class="nv">pkgs</span><span class="o">.</span><span class="nv">writeShellApplication</span> <span class="p">{</span>
                  <span class="nv">name</span> <span class="o">=</span> <span class="s2">"composer"</span><span class="p">;</span>

                  <span class="nv">runtimeInputs</span> <span class="o">=</span> <span class="p">[</span>
                    <span class="nv">php</span>
                    <span class="nv">php</span><span class="o">.</span><span class="nv">packages</span><span class="o">.</span><span class="nv">composer</span>
                  <span class="p">];</span>

                  <span class="nv">text</span> <span class="o">=</span> <span class="s2">''</span><span class="err">
</span><span class="s2">                    </span><span class="si">${</span><span class="nv">lib</span><span class="o">.</span><span class="nv">getExe</span> <span class="nv">php</span><span class="o">.</span><span class="nv">packages</span><span class="o">.</span><span class="nv">composer</span><span class="si">}</span><span class="s2"> "$@"</span><span class="err">
</span><span class="s2">                  ''</span><span class="p">;</span>
                <span class="p">}</span>
              <span class="p">);</span>
            <span class="p">};</span>

            <span class="c"># nix run .#phpunit -- --version</span>
            <span class="nv">phpunit</span> <span class="o">=</span> <span class="p">{</span>
              <span class="nv">type</span> <span class="o">=</span> <span class="s2">"app"</span><span class="p">;</span>
              <span class="nv">program</span> <span class="o">=</span> <span class="nv">lib</span><span class="o">.</span><span class="nv">getExe</span> <span class="p">(</span>
                <span class="nv">pkgs</span><span class="o">.</span><span class="nv">writeShellApplication</span> <span class="p">{</span>
                  <span class="nv">name</span> <span class="o">=</span> <span class="s2">"phpunit"</span><span class="p">;</span>

                  <span class="nv">runtimeInputs</span> <span class="o">=</span> <span class="p">[</span> <span class="nv">php</span> <span class="p">];</span>

                  <span class="nv">text</span> <span class="o">=</span> <span class="s2">''</span><span class="err">
</span><span class="s2">                    </span><span class="si">${</span><span class="nv">lib</span><span class="o">.</span><span class="nv">getExe</span> <span class="nv">pkgs</span><span class="o">.</span><span class="nv">phpunit</span><span class="si">}</span><span class="s2"> "$@"</span><span class="err">
</span><span class="s2">                  ''</span><span class="p">;</span>
                <span class="p">}</span>
              <span class="p">);</span>
            <span class="p">};</span>
          <span class="p">};</span>
        <span class="p">};</span>
    <span class="p">};</span>
<span class="p">}</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">composer.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
    </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ajiyakin/debugphp"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"description"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Sample project to demonstrate how to debug PHP in NeoVim"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"project"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"require"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"guzzlehttp/guzzle"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^7.9"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"require-dev"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"phpunit/phpunit"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^8.5"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"ext-xdebug"</span><span class="p">:</span><span class="w"> </span><span class="s2">"*"</span><span class="p">,</span><span class="w">
        </span><span class="nl">"phpunit/php-code-coverage"</span><span class="p">:</span><span class="w"> </span><span class="s2">"^7.0"</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"license"</span><span class="p">:</span><span class="w"> </span><span class="s2">"MIT"</span><span class="p">,</span><span class="w">
    </span><span class="nl">"autoload"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
        </span><span class="nl">"psr-4"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
            </span><span class="nl">"Ajiyakin\\Debugphp\\"</span><span class="p">:</span><span class="w"> </span><span class="s2">"src/"</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="nl">"authors"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="p">{</span><span class="w">
            </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"AjiYakin"</span><span class="p">,</span><span class="w">
            </span><span class="nl">"email"</span><span class="p">:</span><span class="w"> </span><span class="s2">"ajiyakin91@gmail.com"</span><span class="w">
        </span><span class="p">}</span><span class="w">
    </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">.vscode/launch.json</code>:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"$schema"</span><span class="p">:</span><span class="w"> </span><span class="s2">"https://raw.githubusercontent.com/mfussenegger/dapconfig-schema/master/dapconfig-schema.json"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"version"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.2.0"</span><span class="p">,</span><span class="w">
  </span><span class="nl">"configurations"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Listen for Xdebug"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"php"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"request"</span><span class="p">:</span><span class="w"> </span><span class="s2">"launch"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"port"</span><span class="p">:</span><span class="w"> </span><span class="mi">9003</span><span class="w">
    </span><span class="p">},</span><span class="w">
    </span><span class="p">{</span><span class="w">
      </span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Built-in Server with Xdebug"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"php"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"request"</span><span class="p">:</span><span class="w"> </span><span class="s2">"launch"</span><span class="p">,</span><span class="w">
      </span><span class="nl">"runtimeArgs"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
        </span><span class="s2">"-S"</span><span class="p">,</span><span class="w"> </span><span class="s2">"localhost:8080"</span><span class="w">
      </span><span class="p">],</span><span class="w">
      </span><span class="nl">"port"</span><span class="p">:</span><span class="w"> </span><span class="mi">9003</span><span class="w">
    </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">.user.ini</code> (per-directory php ini configuration file):</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="py">xdebug.mode</span><span class="p">=</span><span class="s">debug</span>
<span class="py">xdebug.client_host</span><span class="p">=</span><span class="s">0.0.0.0</span>
<span class="py">xdebug.client_port</span><span class="p">=</span><span class="s">9003</span>
<span class="py">xdebug.start_with_request</span><span class="p">=</span><span class="s">yes</span>
<span class="py">xdebug.idekey</span><span class="p">=</span><span class="s">NEOVIM</span>
</code></pre></div></div>

<h3 id="for-cli-app">For CLI App</h3>
<p>Here is running order for CLI App:</p>
<ol>
  <li>Add breakpoint in <code class="language-plaintext highlighter-rouge">App.php</code></li>
  <li>Run the <em>Listen for Xdebug</em> from launch configuration</li>
  <li>Run the cli with command: <code class="language-plaintext highlighter-rouge">XDEBUG_CONFIG="idekey=NEOVIM" php -c .user.ini ./vendor/bin/phpunit src/App.php</code></li>
</ol>

<h3 id="for-server-app">For Server App</h3>
<p>It is much more simple to run server app:</p>
<ol>
  <li>Add breakpoint in <code class="language-plaintext highlighter-rouge">index.php</code></li>
  <li>Run <em>Built-in Server with Xdebug</em></li>
  <li>Trigger breakpoint by sending request to the corresponding routing/endpoint.</li>
</ol>

<h3 id="notes">Notes</h3>
<p>I am not sure why the server is not shutting down when I stop the debugger for server app, I will need to figure out later, but a workaround for this is to manually kill the server with this command:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo kill</span> <span class="nt">-9</span> <span class="si">$(</span>lsof <span class="nt">-t</span> <span class="nt">-i</span> tcp:8080<span class="si">)</span>
</code></pre></div></div>]]></content><author><name>AjiYakin</name></author><category term="Dev" /><category term="Documentation" /><category term="Development" /><category term="Documentation" /><summary type="html"><![CDATA[Sometimes I need to debug PHP code in two different situations: a CLI (command-line) app and a web server app. While the way to run each one is slightly different, the steps are subtle, and I often forget the correct order for each case.]]></summary></entry><entry><title type="html">Harapan dan Kekecewaan - Mengatur Expektasi</title><link href="https://theikalman.github.io/harapan-dan-kekecewaan-mengatur-expektasi" rel="alternate" type="text/html" title="Harapan dan Kekecewaan - Mengatur Expektasi" /><published>2020-06-10T06:00:00+00:00</published><updated>2020-06-10T06:00:00+00:00</updated><id>https://theikalman.github.io/harapan-dan-kekecewaan-mengatur-expektasi</id><content type="html" xml:base="https://theikalman.github.io/harapan-dan-kekecewaan-mengatur-expektasi"><![CDATA[<p>Sekitar 2 bulan yang lalu, saya menyelesaikan membaca buku dengan judul
<em>Sebuah Seni untuk Bersikap Bodo Amat</em>, ini adalah versi terjemahan dari versi
bahasa inggrisnya yaitu <em>The Subtle Art of Not Giving a F*ck</em>. Buku ini
berhasil membuka mata saya tentang cara pandang saya terhadap harapan saya
sendiri. Sebagai background, saya ini orang yang senang sekali berhayal,
berharap, bermimpi, apapun lah istilahnya, yang kemudian mendorong saya untuk
berekspektasi bahwasannya sesuatu atau seseorang tersebut adalah harus sama
dengan apa yang saya ekspektasikan, yang mana seringkali tidak sesuai.</p>

<p>Buku ini mencoba memberikan gambaran tentang bagaimana susahnya berharap
terhadap sesuatu atau seseorang lalu kemudian kita berharap sesuatu atau
seseorang tersebut akan persis sesuai dengan apa yang kita harapkan, yang
akhirnya kita akan memberikan perhatian lebih terhadap hal ini, dan perhatian
inilah yang akan membuat kita lupa untuk hanya mengerjakan apa-apa yang
sebenarnya penting buat kita saja. Perhatian berlebihan ini yang bisa membuat
orang menyalahkan keadaan, menyalahkan orang lain, menyalahkan lingkungan dan
mungkin dalam tingkat yang lebih parah kita bisa jadi malah ikut campur sama
urusan orang diluar keharusan kita. Ikut campur disini tidak hanya langsung
berinteraksi yah, tapi “sekedar ikut memikirkan” atau bahkan silent judgment
juga menurut saya sudah bagian dari ikut campur.</p>

<p>Kata-kata yang paling saya ingat dalam buku tersebut adalah</p>

<blockquote>
  <p>Kita tidak bertanggung jawab untuk apa yang orang lain lakukan terhadap kita,
tapi kita bertanggung jawab penuh terhadap reaksi yang kita lakukan terhadap
sikap seseorang tersebut.</p>
</blockquote>

<p>Pada tahap ini saya sudah tidak mau lagi berharap sesuatu atau seseorang
itu menjadi apa yang saya fikirkan, tapi kalo ada kesempatan yang bisa saya
bantu untuk menjadikan sesuatu atau seseorang itu lebih baik ya saya coba
bantu. Dengan begini, saya tidak lagi repot dengan kekecewaan, saya jadi lebih
sadar tentang apa yang sebenarnya harus saya lakukan. Dan pastinya jadi lebih
<em>less stress</em>.</p>

<p>Kalo lagi ngomongin mencoba mengubah apa yang diluar kendali kita itu saya
jadi teringat pepatah, saya sendiri lupa siapa yang mengatakannya,
pepatahnya seperti ini</p>

<blockquote>
  <p>Ketika remaja, saya berusaha mengubah dunia. Ketika dewasa saya berusaha
mengubah lingkungan saya, dan sekarang saya hanya berusaha mengubah
diri saya sendiri.</p>
</blockquote>

<p>Jadi buat saya, sudah cukup berharap pada sesuatu atau seseorang, cukuplah
berharap pada yang pasti tidak mengecewakan, yaitu Alloh SWT. Dan mulailah
mengubah diri sendiri karena itu yang paling mudah dilakukan dan kita punya
kontrol penuh terhadap diri kita sendiri.</p>

<hr />

<p>Tulisan ini agak sedikit melenceng dari kebiasa saya, yaitu hanya menulis
soal teknikal di blog ini. Tapi ya apa boleh buat, saya ingin mendokumentasikan
apapun yang saya pelajari dalam hal apapun. Semoga ini bisa menjadi pelajaran
juga bagi yang membaca.</p>]]></content><author><name>AjiYakin</name></author><category term="Learning" /><category term="Life learn" /><category term="Book" /><summary type="html"><![CDATA[Sekitar 2 bulan yang lalu, saya menyelesaikan membaca buku dengan judul Sebuah Seni untuk Bersikap Bodo Amat, ini adalah versi terjemahan dari versi bahasa inggrisnya yaitu The Subtle Art of Not Giving a F*ck. Buku ini berhasil membuka mata saya tentang cara pandang saya terhadap harapan saya sendiri. Sebagai background, saya ini orang yang senang sekali berhayal, berharap, bermimpi, apapun lah istilahnya, yang kemudian mendorong saya untuk berekspektasi bahwasannya sesuatu atau seseorang tersebut adalah harus sama dengan apa yang saya ekspektasikan, yang mana seringkali tidak sesuai.]]></summary></entry><entry><title type="html">Gagal Shutdown di Lenovo Flex 14 dengan Linux Kernel 5.3 (Ubuntu 18.04)</title><link href="https://theikalman.github.io/gagal-shutdown-lenovo-flex-ubuntu-18.04-kernel-5.3" rel="alternate" type="text/html" title="Gagal Shutdown di Lenovo Flex 14 dengan Linux Kernel 5.3 (Ubuntu 18.04)" /><published>2020-06-01T08:15:00+00:00</published><updated>2020-06-01T08:15:00+00:00</updated><id>https://theikalman.github.io/gagal-shutdown-lenovo-flex-ubuntu-18.04-kernel-5.3</id><content type="html" xml:base="https://theikalman.github.io/gagal-shutdown-lenovo-flex-ubuntu-18.04-kernel-5.3"><![CDATA[<p>Setelah sekitar hampir 2 minggu yang lalu pas buka tas dan lihat laptop
masih nyala, agak heran juga karena gak biasanya linux kayak gini,
dulu pernah ngamalin (sekitar 5-6 tahun lalu) tapi itu di Windows bukan
Linux. Baru setelah satu minggu ada waktu buat start lakuin research karena
harus ngurus ini itu dulu (momen idul fitri) ketahuan lah penyebabnya
kenapa, itupun setelah 1 minggu research juga :)</p>

<p>Laptop Saya adalah Lenovo Flex 14. Laptop kantor sebenarnya, lol :)</p>

<p>Soal penyebabnya, Saya masih ragu sebenarnya, namun gambaran besarnya
adalah karena kernel Linux versi 5.3 yang sekarang nempel di Ubuntu 18.04
Saya itu ada bug yang entah bagaimana gagal membunuh semua proses yang
jalan di komputer Saya tersebut. Berikut referensi yang berkaitan dengan
masalah ini:</p>

<ul>
  <li><a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1594023">https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1594023</a></li>
  <li><a href="https://askubuntu.com/questions/125844/shutdown-does-not-power-off-computer">https://askubuntu.com/questions/125844/shutdown-does-not-power-off-computer</a></li>
  <li><a href="https://unix.stackexchange.com/questions/457967/shutdown-does-not-power-off-why">https://unix.stackexchange.com/questions/457967/shutdown-does-not-power-off-why</a></li>
</ul>

<p>Untuk fix, ada dua solusi yang Saya temukan dari deretan resource diatas,
nambah <code class="language-plaintext highlighter-rouge">acpi=force</code> di grub pada saat linux dijalankan, dan yang kedua
adalah upgrade kernel. Saya sudah coba yang pertama, set
<code class="language-plaintext highlighter-rouge">GRUB_CMDLINE_LINUX_DEFAULT</code> di file grub menjadi</p>

<p><code class="language-plaintext highlighter-rouge">GRUB_CMDLINE_LINUX_DEFAULT="quiet splash acpi=force"</code></p>

<p>dari yang asalnya</p>

<p><code class="language-plaintext highlighter-rouge">GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"</code></p>

<p>yang, ternyata tidak berhasil, komputer Saya tetap tidak bisa mati secara
normal. LCD screen mati, tapi backlight keyboard tetap nyala, pun tombol
power tetap mengindikasikan nyala, kipas ya juga sama masih kedengaran
tetep muter.</p>

<p>Solusi yang berhasil adalah yang kedua, yaitu upgrade kernel Linux, meskipun
sebenarnya agak takut juga karena takutnya malah gagal dan, ya harus benerin
dari awal. Ini bukan takut sih, tapi lebih ke males :smile:</p>

<p>Saya coba lihat versi kernel Linux terakhir, ternyata yang terakhir dirilis
(versi stable) adalah <code class="language-plaintext highlighter-rouge">5.6.14</code> sementara yang terinstall di komputer Saya
adalah <code class="language-plaintext highlighter-rouge">5.3</code>. Ya sudah Saya putuskan coba install yang terakhir tersebut.</p>

<p><img src="/postimages/2020-06-01-gagal-shutdown-lenovo-flex-ubuntu-18.04-kernel-5.3_kernel_latest_version.png" alt="Latest Linux Kernel Version" /></p>

<p>Cara installnya Saya ikutin langkah-langkahnya sesuai yang ada di sini:</p>

<p><a href="https://www.tecmint.com/upgrade-kernel-in-ubuntu/">https://www.tecmint.com/upgrade-kernel-in-ubuntu/</a></p>

<p>Kurang lebih download file berikut</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>linux-headers-5.6.14-050614_5.6.14-050614.202005200733_all.deb
linux-headers-5.6.14-050614-generic_5.6.14-050614.202005200733_amd64.deb
linux-image-unsigned-5.6.14-050614-generic_5.6.14-050614.202005200733_amd64.deb
linux-modules-5.6.14-050614-generic_5.6.14-050614.202005200733_amd64.deb
</code></pre></div></div>

<p>dari sini: <a href="https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.6.14/">https://kernel.ubuntu.com/~kernel-ppa/mainline/v5.6.14/</a></p>

<p>Setelah itu install semua file tersebut dengan perintah: <code class="language-plaintext highlighter-rouge">sudo dpkg -i *.deb</code></p>

<blockquote>
  <p>Catatan:</p>

  <p>Pada saat nginstall, ada warning, kurang lebih warningnya mengatakan
bahwa ada beberapa firmware yang hilang dibawah folder <code class="language-plaintext highlighter-rouge">/lib/firmware/amdgpu/</code>.
Salah satu firmware yang hilang adalah <code class="language-plaintext highlighter-rouge">navi12_asd.bin</code> tapi setelah Saya coba
cari-cari di <a href="https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/amdgpu">repo firmware linuxnya</a>
gak nemu, akhirnya tidak Saya hiraukan warning tersebut, walhasil tetep
jalan kok :smile:</p>
</blockquote>

<p>Dan setelah langkah tersebut, reboot komputer dan setelah nyala lagi, pastiin
kernel yang diinstall tadi sudah berhasil di load dengan command <code class="language-plaintext highlighter-rouge">uname -rs</code>,
kalo yang muncul versi <code class="language-plaintext highlighter-rouge">5.6.14</code> ya berarti berhasil. Dan di kasus Saya, berhasil.
Saya jadi bisa shutdown komputer Saya secara normal dan matinya <em>sangat super cepat</em>,
gak kayak Windows yang super lemot kalo matiin komputer. Lol.</p>

<p>Ok, itu saja, Saya juga udah males nulisnya, bye.</p>]]></content><author><name>AjiYakin</name></author><category term="Troubleshot" /><category term="Linux" /><category term="Lenovo Flex 14" /><summary type="html"><![CDATA[Setelah sekitar hampir 2 minggu yang lalu pas buka tas dan lihat laptop masih nyala, agak heran juga karena gak biasanya linux kayak gini, dulu pernah ngamalin (sekitar 5-6 tahun lalu) tapi itu di Windows bukan Linux. Baru setelah satu minggu ada waktu buat start lakuin research karena harus ngurus ini itu dulu (momen idul fitri) ketahuan lah penyebabnya kenapa, itupun setelah 1 minggu research juga :)]]></summary></entry><entry><title type="html">EFS Ter-Mount dan Terbaca Tapi ECS Tidak Berhasil Menyimpan Data Ke EFS</title><link href="https://theikalman.github.io/efs-termount-dan-terbaca-tapi-ecs-tidak-berhasil-menyimpan-ke-efs" rel="alternate" type="text/html" title="EFS Ter-Mount dan Terbaca Tapi ECS Tidak Berhasil Menyimpan Data Ke EFS" /><published>2017-01-19T04:08:00+00:00</published><updated>2017-01-19T04:08:00+00:00</updated><id>https://theikalman.github.io/efs-termount-dan-terbaca-tapi-ecs-tidak-berhasil-menyimpan-ke-efs</id><content type="html" xml:base="https://theikalman.github.io/efs-termount-dan-terbaca-tapi-ecs-tidak-berhasil-menyimpan-ke-efs"><![CDATA[<p>Seharian kemarin, berkutat sama AWS (lagi). Ya kan emang kerjaannya pake AWS :smile:
Ada hal yang aneh ketika cluster di ECS yang sudah saya set-up agar nge-mount
EFS tidak bisa menulis ke EFS, ato singkatnya ECS tidak berhasil menulis data
ke EFS.</p>

<p>Tapi sebelum Saya ngasih tau alesan kenapa bisa kejadian seperti itu, dan
menceritakan bagaimana Saya nge-fix masalah tersebut, ada baiknya Saya kasih
gambaran umum dulu apa itu EFS, ECS dan AWS itu sendiri. Biar yang baca,
meski pemula gak bingung :smile:</p>

<h2 id="aws-amazon-web-service">AWS (Amazon Web Service)</h2>
<p>Singkatnya ini services yang ditawarkan Amazon untuk para pengembang, terutama
dilingkungan web, ya gak jauh-jauh sama cloud-computing-lah. Service yang
ditawarkan juga beragam, dari mulai VPS, AWS-Lambda (bisa jalanin kodingan
tanpa butuh server, maksudnya kita gak perlu set-up server), termasuk kalo
yang suka ngopre IoT, AWS juga nyediain yang namanya AWS IoT, dan services
yang lainnya banyak (banget), jadi gak bisa saya sebutin – lagian gak dibayar
juga sama AWS-nya :smile:.</p>

<h2 id="ecs-ec2-container-service">ECS (EC2 Container Service)</h2>
<p>Sebelumnya kalo belum tahu apa itu EC2, EC2 itu ya anggaplah komputer biasa
(aslinya virtual-machine). Terus, nyambungnya sama ECS apaan? ECS sendiri
sebenarnya (kalo saya bilang) service yang disediain AWS untuk manage
docker yang ada di EC2-nya itu sendiri. Apa itu docker? Kayaknya yang ini
tolong cari tahu sendiri ya :smile: ECS ini ketika kita buat instance
docker (container – docker run kalo di lokal komputermu) akan membuat 
sendiri EC2 instance untuk nyimpen container docker-nya tersebut,
juga, kalau kita jalanin 2 atau lebih docker container ya ECS bisa kita
set supaya nambah sendiri (kalo misal kurang) EC2-nya.</p>

<h2 id="efs-elastic-file-system">EFS (Elastic File System)</h2>
<p>Kalo yang ini, anggaplah storage biasa, yang bisa dilepas-pasang
ke EC2 tadi itu, yang mana EC2 itu juga dipake sama ECS.</p>

<p>Penjelasannya singkat saja, hanya untuk memberi gambaran istilah-istilah dari
masalah yang Saya coba dokumentasikan disini. Oke, kalo gitu lanjut.</p>

<h2 id="aku-mau-ngapain">Aku Mau Ngapain?</h2>
<p>Niat Saya (sebenarnya kami, karena ini kerjaan kantor :smile:), adalah
karena si ECS ini sering di-restart (tiap release – dan releasenya bisa
1-2 kali seminggu), jadi ECS gak bisa nyimpen data secara persistent, ato
tetap, jadi pas di restart ya datanya ilang, sementara data yang harus
di proses (yang sebelumnya di download dulu) itu lumayan besar, jadi
ya risih ajah harus download berulang-ulang. Jadi ya niatnya datanya
disimpen di EFS, EFSnya di mount ke ECS, nanti ECS nyimpen datanya
di EFS yang ke-mount tersebut. Singkatnya gitu.</p>

<h2 id="konfigurasi">Konfigurasi</h2>
<p>Konfigurasinya sebenarnya sudah berhasil ngikutin <a href="https://aws.amazon.com/blogs/compute/using-amazon-efs-to-persist-data-from-amazon-ecs-containers/">ini</a>.
Cuma untuk launch-configuration-nya, pake script yang sederhana, gak
seribet yang ditulis di blog tersebut, kayak gini:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Configure ECS cluster</span>
<span class="nb">echo </span><span class="nv">ECS_CLUSTER</span><span class="o">=</span>&lt;NAMA_CLUSTER_DI_ECS&gt; <span class="o">&gt;&gt;</span> /etc/ecs/ecs.config

<span class="c"># EFS configurations</span>
yum <span class="nt">-y</span> <span class="nb">install </span>nfs-utils
<span class="nb">mkdir</span> <span class="nt">-p</span> &lt;PATH_FOLDER_KEMANA_EFS_TSB_AKAN_DI_MOUNT&gt;
mount <span class="nt">-t</span> nfs4 <span class="nt">-o</span> <span class="nv">nfsvers</span><span class="o">=</span>4.1,rsize<span class="o">=</span>1048576,wsize<span class="o">=</span>1048576,hard,timeo<span class="o">=</span>600,retrans<span class="o">=</span>2 &lt;DISINI_DNS_EFSNYA&gt; &lt;PATH_FOLDER_KEMANA_EFS_TSB_AKAN_DI_MOUNT&gt;
</code></pre></div></div>

<p>Dan ini berhasil, disebut berhasilnya gimana? Well, ngeceknya
bisa pake command <code class="language-plaintext highlighter-rouge">df -T</code>, akan keliatan apa saja yang ke mount
ke EC2 tersebut. Dan setelah coba ditulisi, berhasil juga, datanya
ke store ke EFS, begitu juga kalo EFSnya dicoba di mount dari EC2
yang lain, terbaca juga EFS beserta file yang sudah disimpan tadi.</p>

<h2 id="masalah">Masalah</h2>
<p>Salahnya, Saya terlalu yakin kalo si ECS (docker) ini akan berhasil
nge-mount EFS (sesuai konfigurasi path diatas) ke containernya :smile:
Sampe akhirnya kejadian aneh datanya gak mau ke store di EFS.
Padahal dicek dari EC2, EFSnya sudah ke mount. Dan… dicoba ditulisi
dari container dockernya (yang dijalanin otomatis sama si ECS),
datanya kesimpen di EC2nya doang, bukan di EFS.</p>

<p>Iya, Saya yang salah, tolong jangan banting gelas :smile:</p>

<h2 id="solusi">Solusi</h2>
<p>Setelah seharian berkutat, akhirnya nemu <a href="https://forums.aws.amazon.com/thread.jspa?threadID=214845">ini</a>
yang cuma disuruh restart docker daemon sama agent ECSnya doang :smile:</p>

<p>Dicoba…</p>

<p>Dan yup, berhasil. Terus kalo mau otomatis gimana? Ah biasa, disimpen
di launch-configuration-nya itu loh. Tempelin script dibawah ini dipaling
bawah di script launch-configuration-nya, setelah nge-mount EFSnya:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Restart docker daemon and ecs (docker-agent),</span>
<span class="c"># so docker would be able to "see" available EFS</span>
service docker restart <span class="o">&amp;&amp;</span> start ecs
</code></pre></div></div>

<p>Versi lengkap launch-configuration-nya:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span>

<span class="c"># Configure ECS cluster</span>
<span class="nb">echo </span><span class="nv">ECS_CLUSTER</span><span class="o">=</span>&lt;NAMA_CLUSTER_DI_ECS&gt; <span class="o">&gt;&gt;</span> /etc/ecs/ecs.config

<span class="c"># EFS configurations</span>
yum <span class="nt">-y</span> <span class="nb">install </span>nfs-utils
<span class="nb">mkdir</span> <span class="nt">-p</span> &lt;PATH_FOLDER_KEMANA_EFS_TSB_AKAN_DI_MOUNT&gt;
mount <span class="nt">-t</span> nfs4 <span class="nt">-o</span> <span class="nv">nfsvers</span><span class="o">=</span>4.1,rsize<span class="o">=</span>1048576,wsize<span class="o">=</span>1048576,hard,timeo<span class="o">=</span>600,retrans<span class="o">=</span>2 &lt;DISINI_DNS_EFSNYA&gt; &lt;PATH_FOLDER_KEMANA_EFS_TSB_AKAN_DI_MOUNT&gt;

<span class="c"># Restart docker daemon and ecs (docker-agent),</span>
<span class="c"># so docker would be able to "see" available EFS</span>
service docker restart <span class="o">&amp;&amp;</span> start ecs
</code></pre></div></div>

<h2 id="lesson-learned">Lesson Learned</h2>

<h3 id="baca-dokumentasi-secara-seksama">Baca dokumentasi secara seksama</h3>

<p>Karena ternyata, di dokumentasinya ada notes, yang persis “menyinggung”
masalah ini :smile:</p>

<p>Dokumentasinya ada <a href="http://docs.aws.amazon.com/AmazonECS/latest/developerguide/using_data_volumes.html">disini</a>.
Kutipan notes-nya:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>For operating systems that use devicemapper (such as Amazon Linux and the Amazon
ECS-optimized AMI), only file systems that are available when the Docker daemon
is started will be available to Docker containers. You can use a cloud boothook 
to mount your file system before the Docker daemon starts, or you can restart 
the Docker daemon and the Amazon ECS container agent after the file system is 
mounted to make the file system available to your container volume mounts.
</code></pre></div></div>

<p>Sekian untuk hari ini, semoga bermanfaat :thumbsup:</p>

<p>Dan mohon do’akan supaya Saya konsisten nulis di blog karatan ini.</p>]]></content><author><name>AjiYakin</name></author><category term="Troubleshot" /><category term="AWS" /><category term="ECS" /><category term="EFS" /><category term="DevOps" /><summary type="html"><![CDATA[Seharian kemarin, berkutat sama AWS (lagi). Ya kan emang kerjaannya pake AWS :smile: Ada hal yang aneh ketika cluster di ECS yang sudah saya set-up agar nge-mount EFS tidak bisa menulis ke EFS, ato singkatnya ECS tidak berhasil menulis data ke EFS.]]></summary></entry><entry><title type="html">Setting Touch-Pad di Elementary OS Freya</title><link href="https://theikalman.github.io/setting-touch-pad-di-elementary-os-freya" rel="alternate" type="text/html" title="Setting Touch-Pad di Elementary OS Freya" /><published>2015-12-13T02:44:00+00:00</published><updated>2015-12-13T02:44:00+00:00</updated><id>https://theikalman.github.io/setting-touch-pad-di-elementary-os-freya</id><content type="html" xml:base="https://theikalman.github.io/setting-touch-pad-di-elementary-os-freya"><![CDATA[<p>Kebetulan 2 minggu yang lalu saya beli laptop baru dan… ya biasa, instalasi
dan ya gitu, melakukan beberapa setting supaya lebih ‘gue banget’. Kebetulan
juga (banyak kebetulannya) saya liat video macbook yang ‘nggeser workspacenya
enak banget pake 4 jari, srettt… Walhasil, sayapun jadi <em>kabita</em> dan
langsung nyari-nyari tools apa yang bisa saya pake.</p>

<p>Okeh, akhirnya ada beberapa tools yang ternyata bisa saya gunakan untuk
memaksimalkan kemampuan touch-pad saya tersebut, setelah sebelumnya cuma
dipake buat scroll atas bawah pakek dua jari doang :smile:</p>

<p>Tools yang bisa dipake bisa macem-macem, dan ternyata secara bawaan di
elementary os juga ternyata sudah ada, yaitu <a href="https://launchpad.net/canonical-multitouch/ginn">ginn</a> dan setelah saya
coba-coba browsing dan coba melakukan beberapa konfigurasi dengan hasil
hampir 70% touch-pad saya tidak bekerja dengan baik. Sebenarnya sama ginnya
(touch-pad saya kedetect) hanya saja entah kenapa <a href="https://launchpad.net/canonical-multitouch/ginn">ginn</a> gak ngejalanin
perintahnya. Terus saya coba-coba install aplikasi lain, dan nemulah
<a href="https://github.com/JoseExposito/touchegg">touchegg</a>. Awalnya agak ragu juga, soalnya direpositorynya sendiri
update-an terakhir adalah 2 tahun lalu, sedangkan saya baru aja beli
laptop 2 minggu yang lalu, bisa saja hardware saya tidak compatible,
fikir saya. Tapi setelah saya coba akhirnya justru malah hasilnya lebih baik,
dan langsung ajah saya coba cari-cari konfigurasi yang orang lain pakek buat
aplikasi ini, dan akhirnya nemu juga. Saya lupa dari mana sumbernya :smile:
tapi mudah-mudahan ‘mpunya’ gak ngamuk :smile: dan saya backup langsung di
<a href="https://gist.github.com/ajiyakin/5a7254158852cbe901ce">gists</a> saya, supaya nanti saya bisa pakek lagi kalo suatu saat saya install
ulang lagi.</p>

<p>Oke, berikut ini step buat masang <a href="https://github.com/JoseExposito/touchegg">touchegg</a> di elementary os:</p>

<ol>
  <li>Install <a href="https://github.com/JoseExposito/touchegg">touchegg</a> dengan command: <code class="language-plaintext highlighter-rouge">sudo apt-get install touchegg</code> atau build
langsung dari source codenya.</li>
  <li>Tambahkan file konfigurasinya, kopi dari <a href="https://gist.github.com/ajiyakin/5a7254158852cbe901ce">sini</a>, dan simpan di
<code class="language-plaintext highlighter-rouge">~/.config/touchegg/touchegg.conf</code></li>
  <li>Tambahkan <a href="https://github.com/JoseExposito/touchegg">touchegg</a> agar dijalankan pas start-up, caranya ada di
<em>System Settings</em> dibagian <em>Applications</em> dan di tab <em>Startup</em> dan klik
tanda plus (+) di bagian kiri bawah dan tuliskan <code class="language-plaintext highlighter-rouge">/usr/bin/touchegg</code> lalu
tekan enter.</li>
  <li>Selesai, coba logout dan login lagi. Terus coba geser workspace dengan 4
jari (kekiri atau kekanan). Atau expands workspace dengan slide 4 jari
kearah atas.</li>
</ol>

<p>Itu ajah. Untuk distro linux yang lain mungkin tidak terlalu jauh berbeda
:smile:</p>]]></content><author><name>AjiYakin</name></author><category term="Troubleshot" /><category term="Linux" /><category term="Troubleshot" /><summary type="html"><![CDATA[Kebetulan 2 minggu yang lalu saya beli laptop baru dan… ya biasa, instalasi dan ya gitu, melakukan beberapa setting supaya lebih ‘gue banget’. Kebetulan juga (banyak kebetulannya) saya liat video macbook yang ‘nggeser workspacenya enak banget pake 4 jari, srettt… Walhasil, sayapun jadi kabita dan langsung nyari-nyari tools apa yang bisa saya pake.]]></summary></entry><entry><title type="html">Apa Itu DevOps</title><link href="https://theikalman.github.io/apa-itu-devops" rel="alternate" type="text/html" title="Apa Itu DevOps" /><published>2015-11-17T19:21:00+00:00</published><updated>2015-11-17T19:21:00+00:00</updated><id>https://theikalman.github.io/apa-itu-devops</id><content type="html" xml:base="https://theikalman.github.io/apa-itu-devops"><![CDATA[<p>Awalnya saya agak mengkerutkan dahi ketika <em>lead</em> programmer saya bilang
“rencananya kita mau pakek <strong>Ansible</strong>, supaya proses <em>release</em> jadi lebih
enteng”. Segera setelah itu, (masih didepan <em>lead</em> saya) langsung saya buka
<em>browser</em> terus masukkin keyword “Ansible”. Haha, ternyata saya baru sadar
kalo saya hidup dalam “kardus”.</p>

<p>Gak lama kemudian <em>lead</em> saya langsung bilang “coba kamu cari-cari tentang
DevOps”. Oke, CuriousMode:On.</p>

<p>Saya mulai baca-baca dan, yup, sekarang mulai faham langkah-langkah bagaimana
proses dari mulai pembuatan aplikasi (coding) sampe ke tahap <em>packaging</em>
dan publishing (sekalipun cuma gambaran). Saya memang <em>programmer</em> baru,
tepatnya baru kerja.</p>

<p>Jujur saja, diawal saja saya kenal <a href="https://www.github.com">github</a> saya agak aneh, kenapa harus
pakai <em>github</em>? Kenapa gak <em>copy</em>-<em>paste</em> manual aja? Memang serepot apa sih
<em>versioning</em> (yang dulu saya menterjemahkan mentah kata ini) sampai harus
pake <em>tools</em> macam <em>github</em> segala? Sekarang saya mulai sadar dengan itu
semua, ya maklumlah dulu seringnya ngoding sendiri jadi ya sekarang perlahan
mulai faham apa yang membedakan antara <em>freelancer</em> dengan
<em>full stack programmer</em>, salah satunya ya penggunaan <em>tools</em> itu. <em>Freelancer</em>
lebih sering memilih <em>tools</em> yang memang ya berguna buat dia (kerja sendiri)
ketimbang <em>full stack programmer</em> yang sering kali milih <em>tools</em> untuk
kemudahan kolaborasi. Oke stop, balik kejalur pembahasan.</p>

<p>Saya jadi bingung, apa hubungannya cerita diatas sama judul?</p>

<p>Secara tidak langsung memang agak gak nyambung (bodo amat, blog saya ini),
yang pasti, <em>tools</em>-<em>tools</em> yang saya sebutkan diatas adalah tidak
lain salah satu dari <em>tools</em> untuk kolaborasi dalam rangka
<em>software development</em>. Dimana sebenarnya sering kali timbul banyak masalah
ketika kita ngoding bareng-bareng, entah itu pas proses penulisan kode,
atau bahkan pada saat proses mau rilis aplikasi. Dan diartikel ini saya coba
nulis apa yang ada dikepala saya soal proses rilis, terutama <em>issue</em> yang
sedang <em>“hot”</em> akhir-akhir ini diproses rilis tersebut. Langsung mulai deh…</p>

<h2 id="bagaiamana-proses-rilis-itu">Bagaiamana proses rilis itu?</h2>
<p>Sebelum saya nulis soal “apa itu <em>DevOps</em>?”, saya mau cerita soal bagaimana
proses rilis aplikasi itu secara garis besar (tentunya ditempat saya). Ini
penting karena nanti akan nyambung dengan judul diatas.</p>

<p>Yaiyalah, kalo gak nyambung ngapain ditulis, tulalit nih penulis.</p>

<p>Anggaplah sekarang kita sudah beres koding dengan keringat dingin mengucur
(seember – karena <em>deadline</em>) dan kita akan merilisnya, dan biasanya
berikut ini adalah langkah-langkah yang dilakukan:</p>

<ol>
  <li>Mindahin <em>source code</em> ke <em>server live</em>.</li>
  <li>Melakukan beberapa konfigurasi yang dibutuhkan.</li>
</ol>

<p>Kelihatannya <em>simple</em> ya?</p>

<p>Pada kenyataanya, sebelum mindahin kodingan ke <em>server live</em> biasanya ada
proses menjalankan semua <em>test</em> yang ada di <em>source code</em> tersebut. Kalo
sering ngelakuin <a href="https://en.wikipedia.org/wiki/Test-driven_development">TDD</a> mungkin gak aneh yah. Kalo hasil tesnya lancar ya
lanjut, kalo ada yang ‘bengkok’ ya dicek ulang, dibenerin dulu.</p>

<p>Proses mindahin kodingan dari tempat <em>development</em> ini juga beda-beda, tapi
kebanyakan sudah <em>clone</em> langsung dari <em>repository</em> ketimbang ngopi atau
ngupload kodingan secara manual lewat <a href="https://en.wikipedia.org/wiki/File_Transfer_Protocol">FTP</a>. Oke, tahap ini mungkin masih
dibilang gampang–lah. Sekalipun ya ribet juga harus login ke <em>server</em>,
terus ngejalanin <code class="language-plaintext highlighter-rouge">git clone</code> atau <code class="language-plaintext highlighter-rouge">git pull origin master</code>. Belum lagi kalo
lupa naro foldernya dimana, ato lupa servernya dimana (yang ini ngarang
biar ‘extreme’) kan bikin repot, tapi udah terlanjur bilang gampang, ya
gampangin aja lah.</p>

<p>Lanjut ke proses kedua, konfigurasi. Nah ini yang agak ribet. Misal sehabis
mindahin <em>source code</em> baru kita harus ngubah beberapa settingan kayak
<em>variable development</em> atau ngeset server jadi mode <em>maintenance</em> ketika
proses rilis ini, ato harus nyeting <em>cron job</em>, dll. Proses ini yang
sebenernya ribet, tapi ‘kelihatan’ gampang dan berulang-ulang, yang padahal
ngabisin waktu banyak, padahal misalnya hanya salah setting <em>cron job</em>, salah
masukin nama <em>file</em> misalnya.</p>

<p>Dari paragrap diatas sekarang mulai ada gambaran gimana proses rilis aplikasi
dari tempat <em>development</em> ke tempat laip (red: <em>live</em>). Dan ya agak ribet
juga, terlebih sebenarnya proses yang berulang-ulang seharusnya memang lebih
baik diotomatisasi biar meminimalisir kesalahan manusia.</p>

<h2 id="devops-itu-apa"><em>DevOps</em> itu apa?</h2>
<p>Sekarang kita baru ‘nginjek’ kata ini, <em>DevOps</em> sendiri menurut <a href="https://en.wikipedia.org/wiki/DevOps">wikipedia</a>
dikatakan campuran kata dari <em>Development</em> dan <em>Operations</em>. Dimana ini
nunjukin tugas-tugas yang berkaitan dengan proses <em>development</em> dan hal-hal
operasional lain atau staf IT lain, ya kayak situkang ngurusin <em>server</em> yang
tugasnya ngupload <em>file</em> kodingan kita ke <em>server live</em> tadi itu, atau
bahkan QA (Quality Assurance) – atau tukang tes.</p>

<h3 id="tugas-devops">Tugas <em>DevOps</em></h3>
<p>Dari pengertian singkat diatas sekarang setidaknya kita tahu bahwa tugas
<em>DevOps</em> itu ya jadi jembatan antara tukang koding, tukang tes, dan tukang
ngurus server. Kalo memang kita sering rilis secara berkala ya sebaiknya
memang <em>aware</em> sama pentingnya <em>DevOps</em> ini, terutama otomatisasi, karena
tentu saja kita nggak mau kalo harus melakukan tugas berulang-ulang yang
memang sebenarnya bisa diotomatisasi, yang pasti bisa menghemat waktu. Nah,
untuk beberapa <em>tools</em> yang berkaitan dengan <em>DevOps</em> ini ada listnya,
sebagai remainder saya juga sih, nih:</p>

<ul>
  <li><a href="http://jenkins-ci.org/">Jenkins</a></li>
  <li><a href="http://www.ansible.com/">Ansible</a></li>
  <li><a href="http://www.seleniumhq.org/">Selenium</a></li>
  <li><a href="https://www.docker.com/">Docker</a></li>
  <li><a href="https://www.atlassian.com/software/bamboo">Bamboo</a></li>
  <li><a href="https://travis-ci.org/">Travis CI</a></li>
  <li>dan lain-lain.</li>
</ul>

<p>Oke, rasanya sudah capek saya nulis. Capek baca nggak? Syukurdeh (mau capek
mau enggak tetep saya sukurin, haha…).</p>

<p>Sekian aja dulu tulisan tentang <em>DevOps</em>, mungkin postingan selanjutnya
saya bakalan nulis tentang tutorial ato hal-hal lain yang masih berkaitan
sama <em>DevOps</em> ini, soalnya memang lagi <em>curious</em> banget sama yang satu ini.</p>

<p>See you…</p>]]></content><author><name>AjiYakin</name></author><category term="DevOps" /><category term="DevOps" /><category term="Learning" /><summary type="html"><![CDATA[Awalnya saya agak mengkerutkan dahi ketika lead programmer saya bilang “rencananya kita mau pakek Ansible, supaya proses release jadi lebih enteng”. Segera setelah itu, (masih didepan lead saya) langsung saya buka browser terus masukkin keyword “Ansible”. Haha, ternyata saya baru sadar kalo saya hidup dalam “kardus”.]]></summary></entry><entry><title type="html">Belajar Ansible</title><link href="https://theikalman.github.io/belajar-ansible" rel="alternate" type="text/html" title="Belajar Ansible" /><published>2015-09-21T18:31:00+00:00</published><updated>2015-09-21T18:31:00+00:00</updated><id>https://theikalman.github.io/belajar-ansible</id><content type="html" xml:base="https://theikalman.github.io/belajar-ansible"><![CDATA[<p>Baru denger istilah <em>DevOps</em>? <em>Ansible</em>? atau bahkan Otomatisasi <em>deployment</em>
aplikasi itu sendiri?</p>

<p>Okeh, sampai disini. Kita sama :smile: Berarti kita punya garis <em>start</em> yang
sama.</p>

<p>Dikantor, kebetulan sedang ada <em>issue</em> tentang <em>DevOps</em>, lebih spesifik lagi
<em>tools</em>/teknologi yang dipake adalah <em>Ansible</em>, jadinya saya penasaran dengan
teknologi ini. Jadi saya fikir, daripada saya belajar sendiri mending saya
sekalian <em>share</em>, paling tidak ini jadi catatan saya ketika saya lupa.</p>

<h3 id="kenapa-harus-diotomatisasi-manual-juga-masih-bisa-kan-toh-cuma-mindahin-source-code-doang-to">Kenapa harus diotomatisasi? Manual juga masih bisa kan? Toh cuma mindahin <em>source code</em> doang to?</h3>
<p>Mmmm… Coba baca kebawah dulu deh :worried:</p>

<hr />

<h2 id="proses-deployment-aplikasi">Proses <em>Deployment</em> Aplikasi</h2>
<p>Proses deployment aplikasi disetiap perusahaan IT memang biasanya berbeda-beda,
tergantung kebijakan dan infrastruktur yang dipilih. Namun demikian, ide dari
proses deployment tersebut ‘cenderung’ sama yaitu dimulai dari pemindahan
<em>source code</em> aplikasi dari tempat <em>development</em> ke <em>server live</em>, lalu
kemudian melakukan beberapa pengaturan yang diperlukan. Nampaknya sederhana,
tapi jika setiap 2 minggu atau 3 minggu atau berapapapun lamanya jarak
<em>release</em> tersebut, tetap saja harus melakukan proses yang ‘cenderung’ berulang
dan sama (dari proses sebelumnya), apa itu efektif? Menghabiskan banyak waktu
dan tenaga untuk proses yang sama, dalam istilah <em>programmer</em> tua itu disebut
<em>DRY (Do not Repeat Yourself)</em>. Oya, belum lagi nanti kalau misal situkang
mindahin <em>source code</em> tersebut lupa mengkonfigurasi file anu, file ini, file
itu, apa tidak malah jadi merepotkan? Belum lagi kalau servernya banyak
gimana?</p>

<h3 id="sebentar-lalu-apa-itu-devops-lebih-tepatnya-siapa">Sebentar, lalu apa itu <em>DevOps</em> (lebih tepatnya “siapa”)?</h3>
<p>Ok, pertanyaan ini sama juga pernah muncul dikepala saya, dari <a href="http://devops.com/2014/01/26/defining-the-dev-and-the-ops-in-devops/">DevOps</a>
sendiri kata ini terdiri dari dua suku kata yaitu <em>Dev</em> dan <em>Ops</em> itu sendiri.
<em>Dev</em> untuk <em>Development</em> (gak tahu deh, <em>development</em> atau <em>developer</em>
:smile:) dan <em>Ops</em> sendiri untuk <em>Operations</em>. Jadi ini gabungan dari pekerjaan
<em>Development</em> dan <em>Operations</em> dimana <em>development</em> cenderung ke pembuatan,
pengembangan dan <em>support</em> aplikasi itu sendiri sedangkan <em>Operations</em> itu
sendiri cenderung ke pekerjaan <em>server administration</em>, <em>packaging</em>, dll.</p>

<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/b5/Devops.svg" alt="DevOps Intersection Image" /></p>

<p><em>Sumber gambar:</em> <a href="https://en.wikipedia.org/wiki/DevOps">Wikipedia - DevOps</a></p>

<blockquote>
  <p>Jika diposisikan, <em>DevOps</em> itu berada di-irisan antara <strong><em>development</em></strong>
<em>(software enginereeng)</em>, <strong><em>Quality Assurance</em></strong> <em>(QA)</em> dan
<strong><em>Technology Operations</em></strong>.</p>
</blockquote>

<p>Untuk lebih jelasnya tentang tanggung jawab dari pekerjaan ini bisa merujuk
ke halaman <a href="http://devops.com/2014/01/26/defining-the-dev-and-the-ops-in-devops/">DevOps</a>.</p>

<p>Sudah liat, banyak yah tanggung jawabnya. Nah justru karena itu, terkadang
proses <em>deployment</em> jadi kelihatan ribet padahal jika di dilihat secara
secara sederhana itu hanya usaha untuk memindahkan <em>source code</em> aplikasi dari
<em>development</em> atau <em>test environment</em> ke <em>live environment</em>.</p>

<p>Ok, sekarang saya (maksud saya pembaca) mulai faham. Lalu selanjutnya apa?</p>

<hr />

<h2 id="apa-itu-ansible">Apa Itu <em>Ansible</em>?</h2>
<p>Saya sudah menjabarkan masalah diatas, jadi <em>simple</em>-nya ya <em>Ansible</em> itu
membantu (atau bahkan mengganti) peran situkang <em>upload source code</em> tadi itu.</p>

<p>Sudah, itu saja, kebanyakan teori malah jadi bosan nanti.</p>

<hr />

<h2 id="cara-kerja-ansible">Cara Kerja <em>Ansible</em></h2>
<p>Mmm… Sederhana saja, saya sudah mau ke praktek ya.</p>

<p>Pernah pake <a href="http://www.ssh.com/">SSH</a>? Kalo belum tahu silahkan baca-baca dulu deh apa itu SSH!</p>

<p><em>Ansible</em> make SSH. Untuk proses yang lebih kompleks lagi <em>Ansible</em> pake
<em>library</em> <a href="https://www.python.org/">Python</a>, tapi ya ujung-ujungnya, pake SSH itu tadi :smile:.</p>

<hr />

<h2 id="praktek">Praktek</h2>

<h3 id="sudah-install-ansible">Sudah install <em>Ansible</em>?</h3>
<p>Sebenarnya saya lupa untuk membuat postingan tentang cara instalasi <em>Ansible</em>
sendiri :smile:. Untuk sementara silahkan merujuk ke halaman dokumentasinya
<a href="https://docs.ansible.com/ansible/intro_installation.html">disini</a>.</p>

<h3 id="file-configurasi-default-ansible">File configurasi (default) <em>Ansible</em>.</h3>
<p>Letak file-file configurasi <em>Ansible</em> sebenarnya berbeda-beda, tergantung
<em>environment</em> yang digunakan biasanya. Tapi, karena saya pake [Ubuntu], jadi
saya hanya akan menuliskan yang saya tahu saja :cry:.</p>

<p>Lokasi konfigurasi <em>Ansible</em> sendiri ada di:</p>

<p><code class="language-plaintext highlighter-rouge">/etc/ansible</code></p>

<p><code class="language-plaintext highlighter-rouge">~/.ansible</code></p>

<p>Atau bisa langsung di dalam folder project <em>Ansible</em> itu sendiri. Sekarang
kita akan mengintip ada apa saja difolder utama konfigurasi <em>Ansible</em> itu
sendiri.</p>

<p>Kita coba ketikan perintah <code class="language-plaintext highlighter-rouge">ls -l /etc/ansible/</code> (untuk linux) dan hasil dari
eksekusi perintah tersebut seperti ini:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    ansible.cfg
    hosts
</code></pre></div></div>

<h4 id="file-ansiblecfg">File <code class="language-plaintext highlighter-rouge">ansible.cfg</code></h4>
<p>File ini berisi konfigurasi utama <em>ansible</em> dimana secara default, jika kita
tidak menggunakan file konfigurasi kita sendiri atau tidak mendeklarasikannya
secara langsung di <em>command-line</em>. Urutan dari file konfigurasi yang akan
digunakan oleh <em>ansible</em> adalah</p>

<ul>
  <li><em>command line</em>, perintah konfigurasi yang dituliskan langsung di <em>terminal</em>
pada saat menjalankan <em>ansible</em>.</li>
  <li>File konfigurasi yang diletakan pada <em>project ansible</em> itu sendiri. Atau
dimana direktori sekarang aktif.</li>
  <li>File konfigurasi yang diletakkan di directori <em>home</em> user, di linux biasanya
terletak di <code class="language-plaintext highlighter-rouge">~/.ansible</code>.</li>
  <li>Terakhir, berada di direktori utama <em>ansible</em> itu sendiri. Di linux sendiri,
biasanya di <code class="language-plaintext highlighter-rouge">/etc/ansible/</code>.</li>
</ul>

<h4 id="file-hosts">File <code class="language-plaintext highlighter-rouge">hosts</code></h4>
<p>File ini berisi konfigurasi <em>server</em> yang akan kita lakukan konfigurasi. Secara
default, file ini tidak berisi apa-apa, kecuali contoh saja.</p>

<h3 id="perintah-sederhana-ad-hoc-command">Perintah sederhana, <em>Ad-Hoc command</em></h3>
<p>Sebelum kita bisa melakukan perintah sederhana ini, kita harus punya <em>server</em>
yang akan kita konfigurasi dulu, untuk demo atau praktek biasanya saya
menggunakan <a href="https://www.virtualbox.org/wiki/Downloads">VirtualBox</a> dan sejenisnya. Dan <strong>pastikan sudah bisa dan sukses
login melalui SSH</strong>. Ini karena <em>ansible</em> menggunakan SSH, ingat tadi diatas!</p>

<p>Disini, saya menggunakan VirtualBox dan IP-nya saya setting static menjadi
<code class="language-plaintext highlighter-rouge">192.168.56.10</code>. Jadi saya akan mencoba mengkonfigurasi <em>server</em> <em>virtual</em>
tersebut.</p>

<p>Ketikan perintah berikut di <em>Terminal</em> (ganti <code class="language-plaintext highlighter-rouge">[username]</code> dengan <em>username</em>
masing-masing yang digunakan untuk mengakses komputer <em>server</em>):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    ansible all -u [username] --ask-pass -m ping
</code></pre></div></div>

<p>Perintah diatas akan melakukan <em>ping</em> (<code class="language-plaintext highlighter-rouge">-m ping</code>) ke semua (<code class="language-plaintext highlighter-rouge">all</code>) hosts yang
kita daftarkan di file <code class="language-plaintext highlighter-rouge">hosts</code> tadi, dalam kasus ini hanya satu <em>server</em>. Dan
ingat, perintah diatas dieksekusi melalui SSH dengan <em>user</em> (<code class="language-plaintext highlighter-rouge">-u [username]</code>)
tertentu. Dan satu lagi, <code class="language-plaintext highlighter-rouge">--ask-pass</code> saya gunakan untuk memerintahkan pada
<em>ansible</em> agar menanyakan <em>password</em> SSH kita ketimbang <em>login</em> melalui
SSH key. Kedepannya saya asumsikan kita tidak perlu lagi memasukkan password
untuk SSH karena kita telah melakukan setting RSA key, jika belum, silahkan
lakukan. Tutorialnya banyak kok di <a href="https://www.google.com">mbah</a>.</p>

<p>Dan jika suskes terkoneksi ke server, responsenya harusnya seperti ini:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>    192.168.56.10 | success &gt;&gt; {
        "changed": false,
        "ping": "pong"
    }
</code></pre></div></div>

<p>Tunggu dulu, perintah untuk ngeping aja kok panjang banget? Bukannya di
subjudul ditulis “perintah sederhana”?</p>

<p>Ya, tentu, karena kita belum melakukan konfigurasi apapun. Itu kenapa
di subjudulnya saya masukkan kata <a href="https://id.wikipedia.org/wiki/Ad_hoc">Ad-Hoc</a>.</p>

<hr />]]></content><author><name>AjiYakin</name></author><category term="Ansible" /><category term="Ansible" /><category term="DevOps" /><category term="Learning" /><summary type="html"><![CDATA[Baru denger istilah DevOps? Ansible? atau bahkan Otomatisasi deployment aplikasi itu sendiri?]]></summary></entry></feed>