Emin Aksehirli2023-07-30T02:38:32+02:00http://memin.tkEmin Aksehirlim@memin.tkSystem76 Oryx Pro 2018 Review - Part 12018-12-24T00:00:00+01:00http://memin.tk/system76-oryx-pro-2018-review<h1 id="summary">Summary</h1>
<p>I have recently bought a <a href="https://system76.com/laptops/oryx">System76 Oryx Pro 2018</a>. I have been planning to buy one for more than a year and finally took a leap of fate and ordered one. I have been using it for more than 2 months now and I wanted to write a review to help people who are trying to decide.</p>
<p><strong>TL;DR</strong>: It’s a <strong>supreme computer</strong> even by only its hardware and probably one of the best choice if you are looking for a GNU/Linux laptop.</p>
<h2 id="pros">Pros</h2>
<ul>
<li>You can customize the hardware configuration</li>
<li>High-resolution matte screen looks amazing</li>
<li>Keyboard and touch pad feels good</li>
<li>It’s a great feeling that somebody else is taking care of the GNU/Linux compatibility of the hardware</li>
<li>GNU/Linux works as it’s supposed to work</li>
<li>It’s designed for tech usage</li>
<li>Great customer service</li>
<li>Default disk encryption</li>
</ul>
<h2 id="cons">Cons</h2>
<ul>
<li>Speakers are a bit muffled</li>
<li>Keyboard organization could be better</li>
<li>It gets hot while playing games</li>
</ul>
<p><img src="/res/img/oryx/oryx_setup.jpg" alt="Setup screen of Pop_os!" /></p>
<h1 id="motivation">Motivation</h1>
<p>I find choosing a computer and especially a notebook computer a very personal and an individual process, hence the name <strong>PC</strong> 😊; therefore, I would like to give some background information about my usage habits and my motivation, so that you can judge my decisions. I have been using Ubuntu as my main operating system since 2007. So, a <em>native</em> GNU/Linux computer is my obviuos choice. My personal computer, which had previously been also my work computer, was a <a href="https://www.dell.com/en-us/work/shop/cty/dell-latitude-e6430-premier-laptop/spd/latitude-e6430">Dell Latitude E6420</a>. I chose that computer because it was supposed to be GNU/Linux-compatible, and I was thinking it <em>was</em> … until I get my Oryx – more on this later. And I am currently using a MacBook Pro Mid-2015 for work.</p>
<p>I am a full time developer, I work from office and sometimes from home. So, mobile-working, and hence the battery life, is not my first priority. I also realized that I use my personal computer mostly to play games or playing around with data mining or machine learning algorithms. Therefore, I prefer performance over mobility, which eliminates the models like <a href="https://system76.com/laptops/gazelle">Gazelle</a>, <a href="https://www.dell.com/en-us/shop/dell-laptops/xps-15/spd/xps-15-9560-laptop">Dell XPS series</a> or <a href="https://puri.sm/products/librem-15/">purism</a>. However, I still want to be able to sit on a couch with my computer on top of my lap or use my computer at a conference, which eliminates the behemoths like <a href="https://system76.com/laptops/serval">Serval</a>.</p>
<p>After a long consideration period, partly because of money matters and partly because my latitude <del>was</del> is still working perfectly, I decided to buy a gaming-capable and linux-compatible notebook. Around the time my Latitude was about turn its 7th year, Oryx Pro 2018 came out; and after a while, I have decided that it was a sign to order one.</p>
<p>Of course I had my concerns:</p>
<ul>
<li>It’s almost impossible to try or even touch Oryx Laptop because they are not in retail shops. This is pretty important since I am quite picky about the UX. I would forever be annoyed if, for example, the left-ctrl key is not at the corner, or I cannot directly use Function keys (F1 - F12).</li>
<li>Oryx Pro is not cheap. It’s frightening to blindly buy something this expensive online.</li>
<li>I don’t live in the US, so, I can get in trouble if it breaks down. Even if it’s ccovered by the warranty, I had to pay a significant amount for shipment.</li>
<li>I wasn’t sure about the build quality. I don’t mind to fix a few minor things and annoyances, I use GNU/Linux after all, but I don’t want to deal with low quality on my everyday PC.</li>
<li>The actual GNU/Linux support. Will the bluetooth work? Can I install any other distribution? Do external screens work?</li>
</ul>
<p>At the end I bought the below configuration and I can gladly say that <em>none of my concerns became a real problem</em>.</p>
<h3 id="my-config">My config:</h3>
<ul>
<li>Pop!_OS 18.04 LTS (64-bit) with full-disk encryption</li>
<li>8 GB GTX 1070 with 2048 CUDA Cores</li>
<li>15.6″ Matte HiDPI 4K HiDPI Display</li>
<li>4.1 GHz i7-8750H (2.2 up to 4.1 GHz – 9MB Cache – 6 Cores – 12 Threads)</li>
<li>32 GB Dual Channel DDR4 at 2666MHz (2× 16GB)</li>
<li>500 GB NVMe PCIe M.2 SSD</li>
<li>No Additional M.2 Drive</li>
<li>No Additional 2.5″ Drive</li>
<li>United States Keyboard</li>
<li>WiFi up to 867 Mbps + Bluetooth</li>
<li>Normal Assembly Service</li>
</ul>
<h1 id="peripherals">Peripherals</h1>
<h2 id="keyboard">Keyboard</h2>
<p>Both the keyboard and the touch pad are crucial; after all, they are the interface that we use to interact with the PCs. To give you a better idea, I went to a retail shop and tried a few popular notebooks to find the most similar one. Oryx’s keyboard is similar to keyboards of the popular gaming notebooks, especially HP OMENs. Overall, the keyboard feels amazing, compared to a pre-2016 MBP keyboard, slighlty bit more resistant to push at first but softer afterwards. It’s back-lit and there are a four special fn-buttons on the keyboard to control the keyboard back-light: 1. turn on/off 2. switch colors 3. increase and 4. decrease the light intensity. <em>Bonus!</em> Check this project to play with colors: <a href="https://gitlab.com/wmww/kb_backlight">https://gitlab.com/wmww/kb_backlight</a></p>
<p>Although I am happy with its current status, keyboard organization could be improved:</p>
<ol>
<li>The arrow bottons do not have any ridges (bumps, indicators) and the layout of keys are very similar to neighboring keys. This makes it harder to align the fingers while looking at the screen.
<video autoplay="" loop="" style="width:100%">
<source src="/res/img/oryx/arrow_keys.mp4" type="video/mp4" />
<source src="/res/img/oryx/arrow_keys.ogm" type="video/ogg" />
Your browser does not support the video tag.
</video>
</li>
<li>Other navigation keys, that are, page up, page down, home, and end, are far away from the arrows. As a person who prefer to use keyboard for navigation instead of the touch pad, this creates a minor annoyance. I know this is not a Oryx-spcific issue but both of the other computers I use solve this issue quite ellegantly, Latitude has all of these keys grouped and MBP uses modifier + arrow keys.</li>
<li>No led indicators for Caps Lock, Num Lock and Scroll Lock.</li>
<li>This is not directly keyboard related but Power Button could be improved. It is too large and feels loose or unaligned. Therefore, it’s difficult to tell whether I can press it correctly. Sometimes, I have to press a few times with different pressure levels to start up the computer.</li>
</ol>
<p>I solved 1st and 2nd points by using the num pad, which has a ridge on 5 and all the navigation buttons within reach. Unfortunately, not all the apps suppport num pad keys. For example, Super + 8 does not go to the upper workspace, or ctrl + page up/down do not change tab in Gnome applications. They work in Firefox though, which is enough for now. Another note is that I have to use Gnome Tweaks to enable the “windows mode” for num pad to be able to select text with shift + num pad arrows.</p>
<p>For the 3rd point, I’ve found <a href="https://extensions.gnome.org/extension/36/lock-keys/">Lock Keys</a> extension, which puts an indicator on the notification panel. This extension should be added to the Pop_Os! distribution as one of the default extensions. By the way, I use caps lock as a ctrl key. It can be configured in Gnome Tweak and releases the strain in left pinky finger. Try it if you haven’t already.</p>
<h2 id="touch-pad">Touch pad</h2>
<p>Touch pad is a pretty standard Synaptics device with two non-touch buttons for left and right click. It works exactly how it should, no problems and nothing extra ordinary – even tough this may not look important, unfortunately I cannot say the same thing for my Latitude’s touchpad which has become so twitchy that it’s not usable anymore. As a reference, I played a <a href="https://www.gog.com/game/anno_1404_gold_edition">strategy game</a> for a few hours without a mouse. After using MBP for a while, touch pad gestures are growing on me. I tried <a href="https://github.com/bulletmark/libinput-gestures">libinput-gestures</a> for 3-finger-swipe workspace switching. It works well; however, because I’ve mapped three-finger touch to middle-mouse-button, everytime I use a three-finger gestures it fires a middle-button click, which may paste the selection. I find four-finger gestures a bit cumborsome but try them if you are ok with them.</p>
<h1 id="photos-for-comparison">Photos for Comparison</h1>
<p>Oryx Pro is slightly larger than the computers I have been using. Here are a few photos for you to compare.</p>
<div class="gallery-box">
<span style="width:70%">
<div>
<h4>MacBook® Pro 15" Mid-2015</h4>
<p>Although they are both 15 inch, Oryx Pro is slightly larger than MacBook pro.</p>
</div>
</span>
<span>
<div>
<a href="/res/img/oryx/vsMbpSize1.jpg" data-lightbox="compare" data-title="Oryx Pro vs Mac Book Pro Mid-2015 Size"><img alt="Oryx Pro vs Mac Book Pro Mid-2015 Size" src="/res/img/oryx/vsMbpSize1_th.jpg" data-lightbox="compare" style="margin-bottom:5px" /></a>
<a href="/res/img/oryx/vsMbpSize2.jpg" data-lightbox="compare" data-title="Oryx Pro vs Mac Book Pro Mid-2015 Thickness"><img alt="Oryx Pro vs Mac Book Pro Mid-2015 Thickness" src="/res/img/oryx/vsMbpSize2_th.jpg" data-lightbox="compare" /></a>
</div>
</span>
</div>
<div class="gallery-box">
<span style="width:70%">
<div>
<h4>MacBook® Pro 15" Mid-2018</h4>
<p>MacBook® Pro 2018 versions are thinner than the previous versions. The availability of ports in Oryx Pro is obvious even from one-side photo.</p>
</div>
</span>
<span>
<a href="/res/img/oryx/vsMbp18Size1.jpg" data-lightbox="compare" data-title="Oryx Pro vs Mac Book Pro 2018 Size"><img alt="Oryx Pro vs Mac Book Pro 2018 Size" src="/res/img/oryx/vsMbp18Size1_th.jpg" data-lightbox="compare" style="margin-bottom:5px" /></a>
<a href="/res/img/oryx/vsMbp18Size2.jpg" data-lightbox="compare" data-title="Oryx Pro vs Mac Book Pro 2018 Thickness"><img alt="Oryx Pro vs Mac Book Pro 2018 Thickness" src="/res/img/oryx/vsMbp18Size2_th.jpg" data-lightbox="compare" /></a>
</span>
</div>
<div class="gallery-box">
<span style="width:70%">
<div>
<h4>Dell Latitude® E6420</h4>
<p>This is my older computer and Oryx is actually replacing this for me. Oryx is much thinner than the latitude and in terms of port availability it is only missing eSata and VGA, none of which is crucial.</p>
</div>
</span>
<span>
<a href="/res/img/oryx/vsLatitudeSize1.jpg" data-lightbox="compare" data-title="Oryx Pro vs Dell Latitude e6420 Size"><img alt="Oryx Pro vs Dell Latitude e6420 Size" src="/res/img/oryx/vsLatitudeSize1_th.jpg" data-lightbox="compare" style="margin-bottom:5px" /></a>
<a href="/res/img/oryx/vsLatitudeSize2.jpg" data-lightbox="compare" data-title="Oryx Pro vs Dell Latitude e6420 Thickness"><img alt="Oryx Pro vs Dell Latitude e6420 Thickness" src="/res/img/oryx/vsLatitudeSize2_th.jpg" data-lightbox="compare" /></a>
</span>
</div>
<hr />
<p>This post tries to compile some of my first impressions on Oryx Pro 2018. I’ll try to write more about battery and performance in another post. Drop me a note if you are curious about anything specific.</p>
Emin Aksehirlihttp://memin.tk/about/Big Hero 6 - Weaponize everything!2015-03-04T00:00:00+01:00http://memin.tk/big-hero-6<p>Let me start by saying that I enjoyed the movie <a href="http://www.imdb.com/title/tt2245084/">Big Hero 6</a>. Pixar always has a special place in my heart and I find this movie better than some of their recent works.</p>
<p>The movie got me thinking about the usage of the technology. As a researcher myself, I would like my research to be used for decent purposes. Therefore, I tend to stay away from some obviously <em>evil</em> areas and focus on more <em>humane</em> ones. Well, this is not specific to research, one should always consider the bigger picture rather than <a href="https://en.wikipedia.org/wiki/Milgram_experiment">just following the orders</a>.</p>
<p><img src="/res/img/bh6/bh6-baymax.jpg" alt="" /></p>
<p>I don’t want to any give spoilers but basically, the movie revolves around a kid (Hiro) who fights against an evil-doer with the help of technology and friends of his late brother.
The movie takes a dramatic turn when the team decides to fight against this evil-doer.
As all of them are inventors/researchers, they quickly turn their current research projects into weapons.
I must say that in real life, researchers cannot use their own projects without an explicit permission from the university or research institute that funds it. I saw cases where years of research effort was thrown away because the university and the researcher cannot agree on terms.
But, maybe this is a topic for another post.</p>
<p><img src="/res/img/bh6/bh6-team.jpg" alt="" /></p>
<p>What troubles me is that the robot of the late brother (Tadashi) is also converted into a <em>warrior</em>.
Tadashi develops a robot to help people: the sole purpose of <em>Baymax</em>, the robot, is to give medical assistance.
Tadashi even designs its exterior as a balloon, so that it would be less intimidating, if it will be at all.
And this robot is converted into a war machine after its creator passed away.</p>
<p>To be fair, it is not only Tadashi’s technology that is converted into a weapon. Hiro’s inventions are used out of their purpose as well, as if they are not <a href="https://en.wikipedia.org/wiki/Grey_goo">risky by themselves</a> anyway.</p>
<p>Of course, the weapons in the movie are used for good, or in other words, <em>they were required to stop evil</em>.
This is a dangerous idea since it is the main argument behind the arm race of the governments.
On the other hand, it is true that in <a href="http://rudaw.net/english/middleeast/syria/07112014">some cases</a> people actually need weapons just to stay alive.
What is worse is, in modern world people who have the power do not need weapons to <a href="https://news.yahoo.com/least-10-dead-migrant-boat-sinks-off-italy-085620839.html">destroy</a> <a href="http://gawker.com/i-cant-breathe-asthmatic-father-dies-after-nypd-chok-1607277393">people</a>.
Usage of excessive violence for social change is a complex topic that I am not capable of elaborating on.
However, I know that the arms and killing people is not a long term solution.</p>
<p><img src="/res/img/bh6/bh6-warmax.jpg" alt="" /></p>
<p>The relation between technology and weapon industry has always been very strong. <a href="https://en.wikipedia.org/wiki/Green_anarchism">Some people</a> even argue that the mere usage of technology destroys the earth as we know it.
I don’t see the whole humanity to stop killing each other in the near future.
But until then, the question remains: can we prevent the misuse of what we develop?</p>
Emin Aksehirlihttp://memin.tk/about/Upgrading to Owncloud 82015-02-22T00:00:00+01:00http://memin.tk/Upgrading-to-Owncloud-8<p>I’ve tried to upgrade my owncloud installation from version 7 to version 8. The upgrades by <a href="http://www.softaculous.com/softaculous/">Softaculous</a> have never been a problem but in this instance it took so long, it didn’t even finished. I’ve tried to restart the update a few times but it stuck every time. During a few days after first the release, search engines did not give me any clue about the problem. But after a couple of days <a href="https://github.com/owncloud/core/issues/14012">this issue</a> hits the first page. The cause of the problem is that all of the encryption keys should be updated (renamed) and this takes time. Apparently, power of the poor shared hosting machine that I use is not enough to complete in time limits. I’ve decided to do the update on my local computer and then redeploy the owncloud installation.</p>
<p>Here are the steps of what I did:</p>
<ol>
<li>Install Apache, MySql, and PHP on my local computer, addressing the <a href="http://doc.owncloud.org/server/8.0/admin_manual/installation/source_installation.html#prerequisites">requirements</a> for an owncloud install.</li>
<li>Download owncloud data folder, I’ll call this folder <code class="language-plaintext highlighter-rouge">data</code>.</li>
<li>Change the group ownership of <code class="language-plaintext highlighter-rouge">data</code> to <code class="language-plaintext highlighter-rouge">www-data</code>, give group read write permission to all of the sub-directories, and give execute permission for all (<code class="language-plaintext highlighter-rouge">a+x</code>) to its parent directories.</li>
<li>Download owncloud installation folder, which resides probably under <code class="language-plaintext highlighter-rouge">~/public_html/</code> or <code class="language-plaintext highlighter-rouge">/var/www/</code>, I’ll call this folder <code class="language-plaintext highlighter-rouge">oc</code>. Put it under apache server root.</li>
<li>Get a dump of the MySql database on the server.</li>
<li>Create a schema and a user on the local MySql server and execute/import the dump.</li>
<li>Update the database and directory information in <code class="language-plaintext highlighter-rouge">oc/config/config.php</code> and also turn off maintenance mode.</li>
<li>Restore encryption backup files as described <a href="https://github.com/owncloud/core/issues/14012#issuecomment-74214431">here</a>.</li>
<li>Open the URL in browser to check whether the owncloud installation works, <strong>do not</strong> start the upgrade since you cannot monitor it.</li>
<li>Stop apache server.</li>
<li>Change time out value from 3600 to 0 (no timeout) in <code class="language-plaintext highlighter-rouge">oc/lib/base.php</code>.</li>
<li>Run upgrade script in <code class="language-plaintext highlighter-rouge">oc</code> by <code class="language-plaintext highlighter-rouge">php ./occ upgrade</code>.</li>
<li>Wait until it finishes, <strong>which took around 12 hours and more than 7 gigs of memory in my case</strong>.</li>
<li>Start apache server and check whether everything is OK.</li>
<li>Stop the server and revert the changes in <code class="language-plaintext highlighter-rouge">oc/config/config.php</code> and <code class="language-plaintext highlighter-rouge">oc/lib/base.php</code>.</li>
<li>Move <code class="language-plaintext highlighter-rouge">encryption_migration-...</code> directories to somewhere else.</li>
<li>Upload upgraded MySql schema, data directory, and installation directory back to server.</li>
</ol>
<p>Installing the required system is easy on GNU/Linux systems. You can follow the guide <a href="https://help.ubuntu.com/community/ApacheMySQLPHP">here</a>. Note on version: I’m still using Ubuntu 12.04 and the default repo still has php version 5.3. Owncloud needs at least 5.4. I used <a href="https://launchpad.net/~ondrej/+archive/ubuntu/php5">this PPA</a> which is mentioned in <a href="http://www.barryodonovan.com/2012/05/22/ubuntu-12-04-precise-pangolin-and-php-5-4-again">this tutorial</a> to upgrade my php version. I’m installing LAMP stack only for this upgrade, therefore the version collisions are not a problem. But if you have other php projects on the computer, be careful. Probably, I’ll remove the packages and repo with <a href="http://manpages.ubuntu.com/manpages/raring/man1/ppa-purge.1.html"><code class="language-plaintext highlighter-rouge">ppa-purge</code></a> after the upgrade.</p>
<p>Since I’ve made the local apache install only for the update, I’ve used the default virtual site and copied <code class="language-plaintext highlighter-rouge">oc</code> folder directly under <code class="language-plaintext highlighter-rouge">/var/www/</code>, well <code class="language-plaintext highlighter-rouge">/var/www/html/</code> in newer apache versions.</p>
<p>Although it isn’t required, I’ve created an sql user with the original credentials and give privileges to an sql schema with the original name. These information can be found in <code class="language-plaintext highlighter-rouge">oc/config/config.php</code>.</p>
<p>I’ve downloaded the <code class="language-plaintext highlighter-rouge">data</code> folder into my home directory and update the location of <code class="language-plaintext highlighter-rouge">data</code> folder in the config file. If you put the <code class="language-plaintext highlighter-rouge">data</code> folder under your home directory, you should also give the execution permission for all (<code class="language-plaintext highlighter-rouge">a+x</code>) to all of its parent folders. While we are editing the config file, turn off the maintenance mode by changing <code class="language-plaintext highlighter-rouge">'maintenance' => true,</code> to <code class="language-plaintext highlighter-rouge">maintenance' => false,</code>.</p>
<p>Restore the backed-up encryption folders as described <a href="https://github.com/owncloud/core/issues/14012#issuecomment-74214431">here</a> and <a href="https://github.com/owncloud/core/issues/14012#issuecomment-73678268">here</a>.</p>
<p>I use owncloud to backup my <a href="https://www.zotero.org/">zotero</a> folder, which is very generous about creating files and directories. Therefore, my files_encryption folder contains 88,065 items although it only totals to 43.9 MB. Since the update time is more about the number of files than the size, I expect the upgrade to take a while. After I checked that the owncloud installation is working, I stopped the apache server and use the console command to upgrade instead of using the web interface. <a href="https://github.com/owncloud/core/issues/14012#issuecomment-73848247">This comment</a> suggest that we use the command <code class="language-plaintext highlighter-rouge">sudo -u www-data php /var/www/owncloud/occ upgrade</code> but I got a warning about the user from the script. Then I just used <code class="language-plaintext highlighter-rouge">php ./occ upgrade</code>.</p>
<p>My first try terminated prematurely because it took more than an hour. Then, I followed <a href="https://github.com/owncloud/core/issues/14012#issuecomment-73902209">this comment</a> and updated <code class="language-plaintext highlighter-rouge">oc/lib/base.php</code> to change the time out value to 0 in the following three lines,</p>
<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="cp"><?php</span>
<span class="c1">//...</span>
<span class="c1">//try to set the maximum execution time to 60min</span>
<span class="nb">set_time_limit</span><span class="p">(</span><span class="mi">3600</span><span class="p">);</span>
<span class="o">@</span><span class="nb">ini_set</span><span class="p">(</span><span class="s1">'max_execution_time'</span><span class="p">,</span> <span class="mi">3600</span><span class="p">);</span>
<span class="o">@</span><span class="nb">ini_set</span><span class="p">(</span><span class="s1">'max_input_time'</span><span class="p">,</span> <span class="mi">3600</span><span class="p">);</span> </code></pre></figure>
<p>to</p>
<figure class="highlight"><pre><code class="language-php" data-lang="php"><span class="cp"><?php</span>
<span class="c1">//...</span>
<span class="c1">//try to set the maximum execution time to 60min</span>
<span class="nb">set_time_limit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="o">@</span><span class="nb">ini_set</span><span class="p">(</span><span class="s1">'max_execution_time'</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="o">@</span><span class="nb">ini_set</span><span class="p">(</span><span class="s1">'max_input_time'</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> </code></pre></figure>
<p>During the upgrade I’ve checked whether it’s running by using <code class="language-plaintext highlighter-rouge">iotop</code>. And monitoring the size of the <code class="language-plaintext highlighter-rouge">files_encryption</code> directory gives an idea about the progress.</p>
<p>Here should be a big <strong>WARNING</strong>: Upgrade took around <em>12 hours</em> on a core i7 computer with SSD and during the upgrade script use more than <em>7 gigs of memory</em>. These are very demanding requirements for a middle class server and definitely impossible to have on a shared hosting. My laptop has 8 gigs of memory in total and still it used around 2 gigs of swap space. SSD prevented the freezes so that it could finish, but I don’t think it was possible without the SSD.</p>
<h2 id="uploading-back">Uploading back</h2>
<p>After ensuring that your local owncloud installation works fine,</p>
<ul>
<li>revert the changes in <code class="language-plaintext highlighter-rouge">oc/config/config.php</code> to the settings on the server,</li>
<li>revert the timeout limits in <code class="language-plaintext highlighter-rouge">oc/lib/base.php</code> to be good a netizen on your shared hosting,</li>
<li>move the <code class="language-plaintext highlighter-rouge">encryption_migration_...</code> directories out of the <code class="language-plaintext highlighter-rouge">data</code> and its sub folders, I will delete them if everything works fine,</li>
<li>make sure you have backup of everything,</li>
<li>take a MySql dump of the local MySql table,</li>
<li>upload the MySql dump to the remote server,</li>
<li>upload the folders using rsync with the commands <code class="language-plaintext highlighter-rouge">rsync -avz --delete oc/ server:~/public_html/oc</code> and <code class="language-plaintext highlighter-rouge">rsync -avz --delete data/ server:~/data</code>. Note the slashes at the end of the source folders; if they are omitted rsync creates the new <code class="language-plaintext highlighter-rouge">oc</code> folder in the <code class="language-plaintext highlighter-rouge">oc</code> folder.</li>
</ul>
<p>This is the easy but not trivial step. Especially, uploading the database is a little bit tedious. Also, it is very important to take backups of everything before you regret.</p>
<p>When you see that everything works fine, delete the temporary backups.</p>
<h3 id="a-note-about-encryption">A note about encryption</h3>
<p>This update become problematic because I use encryption. Since Owncloud’s encryption is not on the client side, it’s possible that the people who has access to server can decrypt the files. Although it’s not the most secure one, I prefer people to go the extra mile to see my files than leaving them in clear. Fortunately, this is the first time upgrade becomes a problem but normally it’s seamless.</p>
<hr />
<p>This the log after installation of the required php packages. It may become handy:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apache2-mpm-worker will be removed
apache2-mpm-prefork (version 2.2.22-1ubuntu1.7) will be installed
libapache2-mod-php5 (version 5.3.10-1ubuntu3.16) will be installed
libmcrypt4 (version 2.5.8-3.1) will be installed
php5-gd (version 5.3.10-1ubuntu3.16) will be installed
php5-intl (version 5.3.10-1ubuntu3.16) will be installed
php5-mcrypt (version 5.3.5-0ubuntu1) will be installed
php5-mysql (version 5.3.10-1ubuntu3.16) will be installed
</code></pre></div></div>
Emin Aksehirlihttp://memin.tk/about/Story of a Logo2015-02-15T00:00:00+01:00http://memin.tk/story-of-a-logo<p>After I had created my previous web site, I was looking for a favicon. Then I decided to use the <a href="http://www.catb.org/hacker-emblem/">hacker symbol</a>:</p>
<p><img src="/res/img/logo/glider.svg" alt="" /></p>
<p>It is known as <a href="https://en.wikipedia.org/wiki/Glider_(Conway's_Life)">glider</a> in <a href="https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life">Conway’s game of life</a>. I like it because the <em>game</em> has very simple rules and it is good representation of the <em>computer logic</em>, while glider is a <em>life form</em> which progresses as a neighborhood. And yes, I consider myself a hacker for a long time. Recently, <em>hacking</em> and <em>the hacker culture</em> has been commercially marketted, so now more people know that it’s not just <em>cracking</em> computers and accounts. But let me state what I understand from hacking with a quote from <a href="https://stallman.org/articles/on-hacking.html">Richard Stallman</a>: “[H]acking means exploring the limits of what is possible, in a spirit of playful cleverness.” This <em>exploration</em> involves questioning the status-quo and challenging the rules of both administrations and nature. I have more comments on hacking culture but that’s for another post, now let’s continue with the logo.</p>
<p>The template I used<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> for the blog involves a logo. Apparently, new trend is to put a circular cropped photo of the author. Although it makes more sense than designing a logo or using a stock image, I don’t want my fellow readers to feel being watched and judged by my stare. Thus, I needed a logo.</p>
<p>Glider completes its cycle in exactly 4 iterations. As a matter of fact, 4 allows a very special form in <a href="https://duckduckgo.com/?q=warhol+4+colors&t=canonical&iax=1&ia=images">pop art</a>. Since this web site will be a combination of art reviews and informatics, I though this would make a very nice logo:</p>
<p><img src="/res/img/logo/4color-square.svg" alt="" /></p>
<p>But, as expected, square form did not match the logo size. Then, I tried this:</p>
<p><img src="/res/img/logo/4color-rect.svg" alt="" /></p>
<p>Unfortunately, the colors did not blend well with the rest of the site. Therefore, I had to fall back to one of these <em>sliglthly</em> more boring versions:</p>
<p><img src="/res/img/logo/logo-grad3.png" alt="" />
<img src="/res/img/logo/logo-grad5.png" alt="" /></p>
<p>Although my original design couldn’t make it to the logo of this web site, I am sure I can use it in the future. If you wanna play with it, the <a href="https://inkscape.org/en/">inkscape</a> file is <a href="/code/glider.svg">here</a>.</p>
<div class="footnotes" role="doc-endnotes">
<ol>
<li id="fn:1" role="doc-endnote">
<p>More like, I ripped from <a href="http://rsms.me">rsms.me</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">↩</a></p>
</li>
</ol>
</div>
Emin Aksehirlihttp://memin.tk/about/Eating up a Golang Channel2015-02-12T00:00:00+01:00http://memin.tk/eating-up-a-golang-channel<p>Channels of <a href="http://golang.org/">Go</a> are great to deal with <em>real</em> concurrent programs. By <em>real</em>, I mean server or daemon processes which are supposed to work or listen permanently, without a down time. The posts on Go blog (<a href="http://blog.golang.org/pipelines">1</a>) (<a href="http://blog.golang.org/go-concurrency-patterns-timing-out-and">2</a>) are very useful to learn the best practices and to understand the merits of channels.</p>
<p>On the other hand, when I use Go as a C substitute for my algorithms, I deal with bulk data. Often, I have to process an array of <em>data</em> as fast as possible. Although <a href="http://blog.golang.org/concurrency-is-not-parallelism">concurrency is not parallelism</a>, I use the goroutines to better utilize 8 (pseudo-)cores of my CPU.
A system similar to the <em>map-reduce</em> framework often comes handy: multiple heavy processors and multiple filters.
<a href="http://blog.golang.org/pipelines">This blog post about pipelines</a> recommends the use of <em>quit channels</em> for graceful shutdowns but their shutdown is not as graceful as I want. As such, using that system does not give me the guaranty of completion.</p>
<p>Let me elaborate with an example. Here are three functions:</p>
<ul>
<li><code class="language-plaintext highlighter-rouge">process</code> iterates over its assigned slice, process each element and send the processed value to <code class="language-plaintext highlighter-rouge">out</code> channel. When it completes its slice, it signals <code class="language-plaintext highlighter-rouge">wg.Done()</code>.</li>
<li><code class="language-plaintext highlighter-rouge">filter</code> reads a value from <code class="language-plaintext highlighter-rouge">in</code> channel and adds it to the final list if it is eligible.</li>
<li><code class="language-plaintext highlighter-rouge">main</code> is a glue code that starts a goroutine for the <code class="language-plaintext highlighter-rouge">filter</code>, shares the data between two processors and prints out the <code class="language-plaintext highlighter-rouge">final</code> values when the processors are finished.</li>
</ul>
<figure class="highlight"><pre><code class="language-go" data-lang="go"><span class="k">func</span> <span class="n">filter</span><span class="p">(</span><span class="n">final</span> <span class="o">*</span><span class="p">[]</span><span class="n">Type</span><span class="p">,</span> <span class="n">in</span> <span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">{</span>
<span class="n">v</span> <span class="o">:=</span> <span class="o"><-</span><span class="n">in</span>
<span class="k">if</span> <span class="n">verify</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="p">{</span>
<span class="o">*</span><span class="n">final</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">final</span><span class="p">,</span> <span class="o">*</span><span class="n">v</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">processor</span><span class="p">(</span><span class="n">data</span> <span class="p">[]</span><span class="kt">int</span><span class="p">,</span> <span class="n">out</span> <span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">,</span> <span class="o">*</span><span class="n">wg</span> <span class="n">sync</span><span class="o">.</span><span class="n">WaitGroup</span><span class="p">){</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">v</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">data</span> <span class="p">{</span>
<span class="n">out</span> <span class="o"><-</span><span class="n">timeConsumingOperation</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Done</span><span class="p">()</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">main</span><span class="p">(){</span>
<span class="n">data</span> <span class="o">:=</span> <span class="n">readData</span><span class="p">()</span>
<span class="n">pipe</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">,</span><span class="m">10</span><span class="p">)</span>
<span class="n">final</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="n">Type</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">100</span><span class="p">)</span>
<span class="k">var</span> <span class="n">wg</span> <span class="n">sync</span><span class="o">.</span><span class="n">WaitGroup</span>
<span class="k">go</span> <span class="n">filter</span><span class="p">(</span><span class="o">&</span><span class="n">final</span><span class="p">,</span> <span class="n">pipe</span><span class="p">)</span>
<span class="n">half</span> <span class="o">:=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">/</span><span class="m">2</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="m">2</span><span class="p">)</span>
<span class="k">go</span> <span class="n">process</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="o">:</span><span class="n">half</span><span class="p">],</span> <span class="n">pipe</span><span class="p">,</span> <span class="o">&</span><span class="n">wg</span><span class="p">)</span>
<span class="k">go</span> <span class="n">process</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">half</span><span class="o">:</span><span class="p">],</span> <span class="n">pipe</span><span class="p">,</span> <span class="o">&</span><span class="n">wg</span><span class="p">)</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Wait</span><span class="p">()</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">final</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>
<p>Well, as experienced <em>gopher</em>s can easily see it has a problem: it exits prematurely. We don’t wait for <code class="language-plaintext highlighter-rouge">filter</code> to finish.</p>
<p>Monitoring the conclusion of <code class="language-plaintext highlighter-rouge">filter</code> is not trivial. Since it’s in an infinite loop, we cannot just use <code class="language-plaintext highlighter-rouge">sync.WaitGroup</code>. Let’s start with the question: when should it say <em>it is finished</em>?</p>
<ul>
<li>When all the <code class="language-plaintext highlighter-rouge">processor</code>s are complete and there is no data in the <code class="language-plaintext highlighter-rouge">channel</code>. Task of signaling <code class="language-plaintext highlighter-rouge">filter</code> about the completion of <code class="language-plaintext highlighter-rouge">processor</code>s looks like a perfect fit for <code class="language-plaintext highlighter-rouge">quit</code> channels, as mentioned in the <a href="http://blog.golang.org/pipelines">blog post</a>. We can introduce a <code class="language-plaintext highlighter-rouge">select</code> statement and <code class="language-plaintext highlighter-rouge">quit</code> channel and let <code class="language-plaintext highlighter-rouge">filter</code> deal with its completion. However, I couldn’t find an elegant and <em>race condition</em> safe solution using quit channel.</li>
</ul>
<p>I turned to collective knowledge and search for an elegant solution. I came accross this very nice <a href="http://stackoverflow.com/a/11131733">answer on stackoverflow</a> and I learned that <a href="http://golang.org/ref/spec#Receive_operator">receive operator</a> returns <strong>two</strong> values: next value on the channel <em>and</em> the channel condition. Here is the table of possible values for <code class="language-plaintext highlighter-rouge">v, ok := <-myChannel</code>:</p>
<table>
<thead>
<tr>
<th style="text-align: right"> </th>
<th style="text-align: center"><code class="language-plaintext highlighter-rouge">len(myChannel) == 0</code></th>
<th style="text-align: center"><code class="language-plaintext highlighter-rouge">len(myChannel) > 0</code></th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: right">Channel open</td>
<td style="text-align: center">Block</td>
<td style="text-align: center"><code class="language-plaintext highlighter-rouge">v == value</code> <br /> <code class="language-plaintext highlighter-rouge">ok == true</code></td>
</tr>
<tr>
<td style="text-align: right">Channel closed</td>
<td style="text-align: center"><code class="language-plaintext highlighter-rouge">v == ZeroValue</code> <br /> <code class="language-plaintext highlighter-rouge">ok == false</code></td>
<td style="text-align: center"><code class="language-plaintext highlighter-rouge">v == value</code> <br /> <code class="language-plaintext highlighter-rouge">ok == false</code></td>
</tr>
</tbody>
</table>
<p>Therefore, signalling of the completion of <code class="language-plaintext highlighter-rouge">process</code>ors can be done over one channel, <em>elegantly</em>.</p>
<p>Final code looks like this:</p>
<figure class="highlight"><pre><code class="language-go" data-lang="go"><span class="k">func</span> <span class="n">filter</span><span class="p">(</span><span class="n">final</span> <span class="o">*</span><span class="p">[]</span><span class="n">Type</span><span class="p">,</span> <span class="n">in</span> <span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">,</span> <span class="n">complete</span> <span class="k">chan</span> <span class="kt">bool</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">{</span>
<span class="n">v</span><span class="p">,</span><span class="n">ok</span> <span class="o">:=</span> <span class="o"><-</span><span class="n">in</span>
<span class="k">if</span> <span class="o">!</span><span class="n">ok</span> <span class="o">&&</span> <span class="n">v</span> <span class="o">==</span> <span class="no">nil</span><span class="p">{</span> <span class="c">// NEW</span>
<span class="n">complete</span> <span class="o"><-</span><span class="no">true</span> <span class="c">// NEW</span>
<span class="p">}</span> <span class="c">// NEW</span>
<span class="k">if</span> <span class="n">verify</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="p">{</span>
<span class="o">*</span><span class="n">final</span> <span class="o">=</span> <span class="nb">append</span><span class="p">(</span><span class="n">final</span><span class="p">,</span> <span class="o">*</span><span class="n">v</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">processor</span><span class="p">(</span><span class="n">data</span> <span class="p">[]</span><span class="kt">int</span><span class="p">,</span> <span class="n">out</span> <span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">,</span> <span class="o">*</span><span class="n">wg</span> <span class="n">sync</span><span class="o">.</span><span class="n">WaitGroup</span><span class="p">){</span>
<span class="k">for</span> <span class="n">_</span><span class="p">,</span><span class="n">v</span> <span class="o">:=</span> <span class="k">range</span> <span class="n">data</span> <span class="p">{</span>
<span class="n">out</span> <span class="o"><-</span><span class="n">timeConsumingOperation</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Done</span><span class="p">()</span>
<span class="p">}</span>
<span class="k">func</span> <span class="n">main</span><span class="p">(){</span>
<span class="n">data</span> <span class="o">:=</span> <span class="n">readData</span><span class="p">()</span>
<span class="n">pipe</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="k">chan</span> <span class="o">*</span><span class="n">Type</span><span class="p">,</span><span class="m">10</span><span class="p">)</span>
<span class="n">final</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">([]</span><span class="n">Type</span><span class="p">,</span><span class="m">0</span><span class="p">,</span><span class="m">100</span><span class="p">)</span>
<span class="k">var</span> <span class="n">wg</span> <span class="n">sync</span><span class="o">.</span><span class="n">WaitGroup</span>
<span class="k">go</span> <span class="n">filter</span><span class="p">(</span><span class="o">&</span><span class="n">final</span><span class="p">,</span> <span class="n">pipe</span><span class="p">)</span>
<span class="n">half</span> <span class="o">:=</span> <span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">)</span><span class="o">/</span><span class="m">2</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Add</span><span class="p">(</span><span class="m">2</span><span class="p">)</span>
<span class="k">go</span> <span class="n">process</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="o">:</span><span class="n">half</span><span class="p">],</span> <span class="n">pipe</span><span class="p">,</span> <span class="o">&</span><span class="n">wg</span><span class="p">)</span>
<span class="k">go</span> <span class="n">process</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="n">half</span><span class="o">:</span><span class="p">],</span> <span class="n">pipe</span><span class="p">,</span> <span class="o">&</span><span class="n">wg</span><span class="p">)</span>
<span class="n">wg</span><span class="o">.</span><span class="n">Wait</span><span class="p">()</span>
<span class="nb">close</span><span class="p">(</span><span class="n">pipe</span><span class="p">)</span> <span class="c">// NEW</span>
<span class="o"><-</span><span class="n">complete</span> <span class="c">// NEW</span>
<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">final</span><span class="p">)</span>
<span class="p">}</span></code></pre></figure>
<hr />
<p><strong>PS</strong>: While I was preparing the example, I realized that <code class="language-plaintext highlighter-rouge">Zero value</code> used often for some types, expecially built-ins like <code class="language-plaintext highlighter-rouge">int</code> and <code class="language-plaintext highlighter-rouge">float</code>. I’m not yet sure about how to handle them. Maybe I’ll return to it in a later post.</p>
Emin Aksehirlihttp://memin.tk/about/Upgrading the key2015-02-10T00:00:00+01:00http://memin.tk/key-upgrade<p>I have been using 2048 bit DSA encryption with just one set of key pairs, i.e., no subkeys. I was thinking that this set-up is more than enough for me. After my first key signing party in <a href="https://archive.fosdem.org/2014/">FOSDEM 2014</a>, I realized that collecting signatures is not easy. So, I decided to improve my <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">encryption practices</a> by using,</p>
<ul>
<li>subkeys for encryption and signing</li>
<li>and a stronger encryption.</li>
</ul>
<p>Using subkeys is a good and recommended practice. There is a great series of blog posts about the importance of it and how to create one <a href="http://spin.atomicobject.com/2013/11/24/secure-gpg-keys-guide/">here</a>. Since these posts are thorough, I will not go into the details of creating a key.
I was warned during the last FOSDEM about the vulnerability of 2048 bit keys and it seems the 4096 bit RSA keys are the new standard. Hence, I’m upgrading the encryption level too.</p>
<p>I found <a href="https://www.apache.org/dev/key-transition.html">this Apache guide</a> that explains how to upgrade a key. Please check it for signing and trusting your new key after creating it.</p>
<p>I don’t want to lose my signatures after the upgrade. Also, I don’t want to weaken the web of trust by removing my key. Therefore, I will re-sign the keys of people and ask them to sign my new key.
Unfortunately, some of the keys are not mutually signed, that is, I didn’t sign keys of some people that signed my key and there are some people that didn’t sign my key but I signed theirs.</p>
<p>Before continuing, let’s synchronize our keyring with the servers with the command <code class="language-plaintext highlighter-rouge">gpg --refresh-keys</code>.</p>
<p>It is easy to find the signatures on my key. To get the fingerprint of my key, I use the command <code class="language-plaintext highlighter-rouge">pgp -K</code>, which lists all the private keys in my keyring. If you have more than one key, you have to identify the one you are using. ID of my key is <code class="language-plaintext highlighter-rouge">90D39AD1</code>. Then, I can find out the signatures on my key with just one command on the console:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gpg --list-sigs 90D39AD1
pub 2048D/90D39AD1 2013-08-31 [expires: 2017-08-29]
uid Emin Akşehirli <emin.aksehirli@qmail.com>
sig 3 90D39AD1 2013-11-29 Emin Akşehirli <emin.aksehirli@qmail.com>
sig 3 DAAADB4C 2013-11-29 John Doe <john.doe@gmail.com>
sig 9AAA4E4B 2014-02-02 Will Dao <will.dao@securemail.com>
....
</code></pre></div></div>
<p>So, with some regex-fu, I’ll be able to extract the ID’s of the signatures on my key.</p>
<p>The harder part is to find the keys that I have signed. Probably there is a script for it but my 5 minute search came empty and I decided to write my own. I am kind of lucky because I know that my local keyring holds all of the keys that I have signed. So, the scripting idea is simple: scan the keys on the keyring and check whether I’ve signed them.</p>
<p>I need to contact two groups of people: People who signed my key and people whose keys I signed. But, I know that signing and managing keys is not the most fun thing to do and the <em>sign-back</em> requests are favour asking, I’ll try to send as few emails as possible. Therefore, I have 3 groups of people:</p>
<ol>
<li>Mutually signed</li>
<li>I signed their key (they did not sign my key)</li>
<li>My key is signed by them (I did not sign theirs)</li>
</ol>
<p>You can find the bash script I’ve written <a href="https://gist.github.com/eminaksehirli/6942929d3a2fd0a3dbdb">here</a>. It creates three files with the keys ID’s in them:</p>
<ol>
<li>/tmp/mutual.txt</li>
<li>/tmp/only_i.txt</li>
<li>/tmp/only_they.txt</li>
</ol>
<p>Next step is to sign and send the keys. For the keys in group 1 and 2, I decided to use <a href="http://manpages.ubuntu.com/manpages/hardy/man1/caff.1.html">caff</a> which can be found in the <code class="language-plaintext highlighter-rouge">signing-party</code> package in Debian and Ubuntu. I modified the email message accordingly and use both my new and old keys to sign it. I referred to <a href="http://mruiz.openminds.cl/blog/index.php/2009/12/03/signing-keys-with-caff/">this</a> and <a href="http://bloc.eurion.net/archives/2010/gpg-key-signing-with-caff/">this</a> blog posts to configure caff. If you like alternatives, <a href="http://www.phildev.net/pius/">PIUS</a> is another utility for signing keys.</p>
<p>I used the following configuration option to use both of my keys for signing the messages <em>[Edit: Please see PS-2 below]</em>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Select this/these keys to sign with
$CONFIG{'local-user'} = [ qw{8E490395F4361444 3209AAD690D39AD1} ];
</code></pre></div></div>
<p>In my case, there were only a few people in group 3. I was too lazy to write a script but that should be perfectly possible to write a script that extracts the email and name of the key owner, create personalized texts, sign it and send.</p>
<p>Since I will not ask anything back for the people in group 2, I will not disturb them. I will sign their keys with my new key and synch with the server.</p>
<hr />
<p><strong>PS-1:</strong> After sending the keys, I got a reply from a fellow friend that he also changed his keys. He provided <a href="http://lapo.it/pgp/transition1.txt">a nice guide for checking the new key</a>, I wish I provided a similar guide.</p>
<p><strong>PS-2:</strong> I got many replies stating that I didn’t use the old key to sign the message. I haven’t check it again but it’s possible that this config is wrong. It’s also possible that popular clients don’t support or don’t make it obvious multiple signatures.</p>
Emin Aksehirlihttp://memin.tk/about/Too Cool to be Forgotten2015-02-05T00:00:00+01:00http://memin.tk/Too-Cool-to-be-Forgotten<p>In <em>Too Cool to be Forgotten</em>, <a href="https://en.wikipedia.org/wiki/Alex_Robinson">Alex Robinson</a> (<a href="/tags/Alex%20Robinson">#</a>) asks a kind of old but still a very interesting question “<strong>What if you can go back to your younger self?</strong>” and then, he gracefully answers it.
<a href="/res/img/tctbf/001_TOOCOOL.jpg" data-lightbox="comic" data-title="Too Cool to be Forgotten Cover"><img class="left" alt="Too Cool to be Forgotten Cover" src="/res/img/tctbf/001_TOOCOOL.jpg" data-lightbox="comic" /></a></p>
<p>What is it like to live by knowing the future? Would you still do the things that you did?
Think about your high school crush that you cannot talk to without stuttering. Could you be much more smoother around him/her if you know that s/he will be looking up to you in 15 years. Or <em>would</em> you ask him/her out if you know that you will find out on your second date that s/he is the most boring person on earth.
Would getting bullied hurt that much if you know you will do fine in a few years?</p>
<p>I like that the book is taking a close look on everyday life of a teenager while keeping the perspective of an adult. For example our education system, putting young people into a room and making them listen to boring lectures 7 to 8 hours a day, 5 times a week… It looks like what <em>things should be</em> because it is almost impossible to see how annoying to sit all day with all these hormones and energy inside.
While I was studying, I wasn’t very happy about the education, but frankly, I wasn’t happy about many things back then. And after graduating I never looked back to do something about it.
This book gave me a chance to rethink about it. Maybe the whole education is intended to be boring as a preparation to <a href="https://www.youtube.com/watch?v=A-rEb0KuopI">the adult life</a>.</p>
<p><a href="/res/img/tctbf/013_TOOCOOL.jpg" data-lightbox="comic" data-title="Too Cool to be Forgotten page 13"><img class="right" alt="Too Cool to be Forgotten page 13" src="/res/img/tctbf/013_TOOCOOL.jpg" data-lightbox="comic" /></a></p>
<p>While I was studying, I used to see people from upper grades as grown ups, people who were in their 30’s were adults and you would be old after 40. Now, I’m 30 something myself and I <em>have</em> the slightest idea about being an adult. Sure, I’m being responsible, reliable etc. but I still don’t feel like an adult, I just know that I have to <em>act</em> like one. Moreover, now I see people in their 50’s as <em>late-young</em>s, let alone being old. I had a good time during my high school years but when I think about having this much information back then, knowing that the 3 (or 4) years is a <em>pinch</em> of a life time, I may have done somethings differently.</p>
<p>I find this is the most suitable comic as the first review of this blog. As a man who left his high school 15 years behind, I could relate to the story, it . It’s a nice read. I recommend it.</p>
<p>It’s a personal story from <a href="https://en.wikipedia.org/wiki/Alex_Robinson">Alex Robinson</a> (<a href="/tags/Alex%20Robinson">#</a>), a straight white man, so I do not expect much about the representation of women or other races. I don’t remember any annoying themes, but there is nothing against the everyday problems either.</p>
<p><a href="/res/img/tctbf/015_TOOCOOL.jpg" data-lightbox="comic" data-title="Too Cool to be Forgotten page 15"><img class="left" alt="Too Cool to be Forgotten page 15" src="/res/img/tctbf/015_TOOCOOL.jpg" data-lightbox="comic" /></a></p>
<p><a href="/res/img/tctbf/016_TOOCOOL.jpg" data-lightbox="comic" data-title="Too Cool to be Forgotten page 16"><img class="right" alt="Too Cool to be Forgotten page 16" src="/res/img/tctbf/016_TOOCOOL.jpg" data-lightbox="comic" /></a></p>
<div style="clear:left"></div>
<p><a href="http://www.topshelfcomix.com/catalog/too-cool-to-be-forgotten/565">Too Cool to be Forgotten on Top Shelf Productions</a></p>
<p><a href="https://www.comixology.eu/Too-Cool-to-Be-Forgotten/digital-comic/21487">Too Cool to be Forgotten on Comixology</a></p>
Emin Aksehirlihttp://memin.tk/about/