<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ahmad Syazwan</title>
    <description>The latest articles on Forem by Ahmad Syazwan (@asyazwan).</description>
    <link>https://forem.com/asyazwan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F125144%2Fc1dd8181-9fa1-4113-ba66-0d2e632411c5.png</url>
      <title>Forem: Ahmad Syazwan</title>
      <link>https://forem.com/asyazwan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/asyazwan"/>
    <language>en</language>
    <item>
      <title>Easy Makefile self-documentation</title>
      <dc:creator>Ahmad Syazwan</dc:creator>
      <pubDate>Wed, 20 May 2020 23:14:35 +0000</pubDate>
      <link>https://forem.com/asyazwan/easy-makefile-self-documentation-1adn</link>
      <guid>https://forem.com/asyazwan/easy-makefile-self-documentation-1adn</guid>
      <description>&lt;p&gt;Here's an easy way to generate makefile help command from its comments that I saw some time ago somewhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.DEFAULT_GOAL := help

help:
    @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'

command1: command2 ## Alias of command2
    echo 'Done!'

command2: ## run command2
    echo 'Running command2'

command3: # Unlisted command
    @echo "I'm private"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;.DEFAULT_GOAL&lt;/code&gt; will run provided make command if none is specified, so by doing &lt;code&gt;make&lt;/code&gt; it will execute &lt;code&gt;make help&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST)&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@&lt;/code&gt; will suppress output because by default make will print out the command it's executing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grep ...&lt;/code&gt; will look for lines that have commands with comments separated by &lt;code&gt;##&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'^[a-zA-Z0-9_-]+:.*?## .*$$'&lt;/code&gt; means search from start of line, any alphanumeric, &lt;code&gt;_&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt; command names followed by &lt;code&gt;:&lt;/code&gt; and any character until &lt;code&gt;##&lt;/code&gt; to end of line (since &lt;code&gt;$&lt;/code&gt; has special meaning in make, we have to escape it so end of line becomes &lt;code&gt;$$&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ftp.gnu.org/old-gnu/Manuals/make-3.80/html_node/make_17.html"&gt;&lt;code&gt;MAKEFILE_LIST&lt;/code&gt;&lt;/a&gt; is make variable that refers to the makefile name in this case&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort&lt;/code&gt; to get alphabetically sorted output&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;pipe the lines through &lt;code&gt;awk&lt;/code&gt; and set the &lt;a href="https://www.gnu.org/software/gawk/manual/html_node/Field-Separators.html"&gt;&lt;code&gt;FS&lt;/code&gt;&lt;/a&gt; field separator to be whatever between the command and help text (modify &lt;code&gt;##&lt;/code&gt; if you want different separator)&lt;/li&gt;
&lt;li&gt;for each match print with &lt;a href="https://en.wikipedia.org/wiki/ANSI_escape_code#Colors"&gt;color&lt;/a&gt;: &lt;code&gt;\033[36m%-15s\033[0m %s\n&lt;/code&gt; so we will get command, &lt;a href="https://www.gnu.org/software/gawk/manual/html_node/Format-Modifiers.html"&gt;padded&lt;/a&gt; with 15 spaces, followed by the help text&lt;/li&gt;
&lt;li&gt;again since we're inside make escape &lt;code&gt;$1&lt;/code&gt; &amp;amp; &lt;code&gt;$2&lt;/code&gt; for column number with &lt;code&gt;$$1&lt;/code&gt; &amp;amp; &lt;code&gt;$$2&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;For commands you don't want to be listed as &lt;code&gt;help&lt;/code&gt; output, simply don't comment or use single &lt;code&gt;#&lt;/code&gt; like &lt;code&gt;command3&lt;/code&gt; example&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;make
command1        Alias of command2
command2        run command2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>makefile</category>
      <category>tips</category>
    </item>
    <item>
      <title>Mojave + VirtualBox</title>
      <dc:creator>Ahmad Syazwan</dc:creator>
      <pubDate>Tue, 21 May 2019 19:33:04 +0000</pubDate>
      <link>https://forem.com/asyazwan/mojave-virtualbox-4ki6</link>
      <guid>https://forem.com/asyazwan/mojave-virtualbox-4ki6</guid>
      <description>&lt;p&gt;I have finally decided to upgrade my macs to Mojave from High Sierra. For my work machine however, VirtualBox simply stopped working and throwing &lt;code&gt;NS_ERROR_FAILURE&lt;/code&gt; on startup. Similar to &lt;a href="https://stackoverflow.com/questions/52689672/virtualbox-ns-error-failure-0x80004005-macos"&gt;this&lt;/a&gt;. Trying to reinstall won't work because the installer will fail at the last step.&lt;/p&gt;

&lt;p&gt;I have tried &lt;em&gt;everything&lt;/em&gt; suggested from disabling Gatekeeper to many many iterations of uninstall/reinstall. Almost every solution suggested clicking &lt;code&gt;Allow&lt;/code&gt; on the Security &amp;amp; Privacy tab but it never appeared.&lt;/p&gt;

&lt;p&gt;What worked for me finally was: &lt;a href="https://apple.stackexchange.com/a/360123/332949"&gt;macos - VirtualBox 5.2 Won't Install on Mac OS 10.13 - Ask Different&lt;/a&gt; which boils down to:&lt;/p&gt;

&lt;p&gt;Go into recovery mode (reboot with Cmd + R during loading screen) and open the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spctl kext-consent disable
spctl kext-consent add VB5E2TV963
spctl kext-consent enable 
reboot
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That is basically the &lt;code&gt;Allow&lt;/code&gt; part which will finally make the install successful. &lt;code&gt;VB5E2TV963&lt;/code&gt; is the Oracle id that we are allowing.&lt;/p&gt;

&lt;p&gt;If you are in similar situation, I hope this will help.&lt;/p&gt;

</description>
      <category>virtualbox</category>
      <category>mojave</category>
    </item>
    <item>
      <title>Moving away from Alpine</title>
      <dc:creator>Ahmad Syazwan</dc:creator>
      <pubDate>Sat, 16 Feb 2019 09:41:12 +0000</pubDate>
      <link>https://forem.com/asyazwan/moving-away-from-alpine-30n4</link>
      <guid>https://forem.com/asyazwan/moving-away-from-alpine-30n4</guid>
      <description>&lt;p&gt;When container movement started getting a lot of traction thanks to docker, there was a real demand for lightweight base image that is optimized for single process, unlike your typical OS. Enter Alpine, a lightweight linux distribution as small as 3MB! It also came with good enough &lt;a href="https://pkgs.alpinelinux.org/packages"&gt;package repository&lt;/a&gt; which helped a lot with adoption. Unfortunately we have stopped adopting Alpine when possible, due to reasons I will outline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adopting Alpine
&lt;/h2&gt;

&lt;p&gt;At work, we started adopting Alpine pretty early on for development, CI, and even production. All is well, except when it’s not. Turns out it’s a lot of work to get packages that are not readily available in Alpine repository. You see, Alpine uses &lt;a href="http://www.musl-libc.org/"&gt;musl&lt;/a&gt; libc instead of &lt;a href="https://www.gnu.org/software/libc/"&gt;glibc&lt;/a&gt; and most popular distros use the latter. So things compiled in Alpine won’t be usable on Ubuntu, for example, and vice versa. It’s great when all packages you need are there in the &lt;code&gt;main&lt;/code&gt; &amp;amp; &lt;code&gt;community&lt;/code&gt; alpine repositories. When that is not the case, you have to build it on your own and &lt;em&gt;hope&lt;/em&gt; that the dependencies are available or at least easy to build as well (against musl).&lt;/p&gt;

&lt;h2&gt;
  
  
  Missing package
&lt;/h2&gt;

&lt;p&gt;One day our CI started failing during docker image build phase. &lt;code&gt;mysql&lt;/code&gt; package (which is just a compatibility package pointing to mariadb) suddenly went missing. We issued the bug report: &lt;a href="https://bugs.alpinelinux.org/issues/8030"&gt;Bug #8030: Missing x86_64 architecture for mysql and mysql-client packages in Alpine v3.3 - Alpine Linux - Alpine Linux Development&lt;/a&gt;. To Natanael's credit, the issue was resolved within the day, but this issue got us to start questioning things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Losing version
&lt;/h2&gt;

&lt;p&gt;I covered this in a &lt;a href="https://ibnusani.com/article/php-curl-segfault/"&gt;previous post&lt;/a&gt;, it's basically about the difficulty in pinning package versions in Alpine. I would continue but I think &lt;a href="https://medium.com/@stschindler/the-problem-with-docker-and-alpines-package-pinning-18346593e891"&gt;this guy&lt;/a&gt; got through the same situation and has the same thoughts. Recommended read.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a package is not available
&lt;/h2&gt;

&lt;p&gt;Developers at work needed to use PHP &lt;a href="http://php.net/manual/en/book.v8js.php"&gt;V8js&lt;/a&gt; for our experimental branch so I had to get the extension for our alpine-based images. Someone got through most of the trouble for me as he detailed the findings in this Github &lt;a href="https://gist.github.com/tylerchr/15a74b05944cfb90729db6a51265b6c9"&gt;gist&lt;/a&gt;. Basically we had to compile &lt;a href="https://gn.googlesource.com/gn/"&gt;GN&lt;/a&gt;, download v8 source, and then build it against musl. Even with the steps laid out, it wasn't a smooth experience. This method is not sustainable for us, considering future updates and patches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syslog limit
&lt;/h2&gt;

&lt;p&gt;Developers rely heavily on app logs via syslog (mounted &lt;code&gt;/dev/log&lt;/code&gt;) and Alpine uses busybox &lt;a href="https://wiki.alpinelinux.org/wiki/Syslog"&gt;syslog&lt;/a&gt; by default. The problem is, messages are truncated at 1024-character limit, which is very small. The root issue is musl has hardcoded limit of 1024 syslog buffer, which is a generous increase from the initial &lt;a href="https://git.musl-libc.org/cgit/musl/commit/src/misc/syslog.c?id=3f65494a4cb2544eb16af3fa64a161bd8142f487"&gt;256&lt;/a&gt;(!) limit but still not enough. This doesn't make sense as a default, and I could not find a way to configure this &lt;em&gt;easily&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final straw
&lt;/h2&gt;

&lt;p&gt;Ubuntu officially launched minimal ubuntu images for cloud / container use around &lt;a href="https://blog.ubuntu.com/2018/07/09/minimal-ubuntu-released"&gt;July&lt;/a&gt; last year.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;These images are less than 50% the size of the standard Ubuntu server image, and boot up to 40% faster.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not only the base image just 29MB in size, but you also get to use all apt packages! All our previous problems with Alpine made it very easy to switch to ubuntu as our base image and we have been satisfied with the switch so far. This in not to say Alpine is not good. It's just not a fit for us.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edit: I need to clarify that this post is not about what's the better alternative. Rather, it's about ditching Alpine. There are definitely few good alternatives to ubuntu-minimal. :)
&lt;/h3&gt;

</description>
      <category>docker</category>
      <category>alpine</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
