<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>Hacker News Personal Blogs 2017 | Top 100 Blogs</title><link>https://hn-blogs.kronis.dev/feed-top100.xml</link><description>A collection of blog posts from users of Hacker News, based on RSS feeds.</description><language>en-US</language><lastBuildDate>Sat, 13 Jun 2026 04:03:20 GMT</lastBuildDate><generator>rfeed v1.1.1</generator><docs>https://github.com/svpino/rfeed/blob/master/README.md</docs><item><title>Migrating from Google (and more)</title><link>https://captnemo.in/blog/2017/12/31/migrating-from-google/</link><description>&lt;div class="toc"&gt;
  &lt;h4 id="contents"&gt;Contents&lt;/h4&gt;

  &lt;ul&gt;
    &lt;li&gt;&lt;a href="#email"&gt;Email&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#google-play-music"&gt;Google Play Music&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#google-keep"&gt;Google Keep&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#phone"&gt;Phone&lt;/a&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;a href="#microg-core"&gt;microG Core&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#unifiedlp"&gt;UnifiedLP&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#maps"&gt;Maps&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#uber"&gt;Uber&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#calendar-contacts"&gt;Calendar/Contacts&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href="#google-play-store"&gt;Google Play Store&lt;/a&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href="#lastpass"&gt;LastPass&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href="#github"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;As part of working on my home-server setup, I wanted to move off few online services to ones that I manage. This is a list of what all services I used and what I’ve migrated to .&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: I got frustrated with &lt;a href="https://music.google.com" title="Google Play Music"&gt;Google Play Music&lt;/a&gt; a few times. Synced songs would not show up across all clients immediately (I had to refresh,uninstall,reinstall), and I hated the client limits it would impose. Decided to try &lt;a href="https://microg.org/" title="MicroG is a free-as-in-freedom re-implementation of Google’s proprietary Android user space apps and libraries."&gt;microG&lt;/a&gt; on my phone at the same time, and it slowly came together.&lt;/p&gt;

&lt;h1 id="email"&gt;Email&lt;/h1&gt;

&lt;p&gt;I’ve been using email on my own domain for quite some time (&lt;code class="language-plaintext highlighter-rouge"&gt;captnemo.in&lt;/code&gt;), but it was managed by a Outlook+Google combination that I didn’t like very much.&lt;/p&gt;

&lt;p&gt;I switched to &lt;a href="http://www.migadu.com/" title="Migadu is email hosting built and operated by humans"&gt;Migadu&lt;/a&gt; sometime last year, and have been quite happy with the service. Their &lt;a href="https://www.migadu.com/privacy/"&gt;Privacy Policy&lt;/a&gt;, and &lt;a href="https://www.migadu.com/procon/"&gt;pro/cons&lt;/a&gt; section on the website is a pleasure to read.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: Email is the central-point of your online digital identity. Use your own-domain, at the very least. That way, you’re atleast protected if Google decides to suspend your account. Self-hosting email is a big responsibility that requires critical uptime, and I didn’t want to manage that, so went with migadu.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why Migadu&lt;/em&gt;: You should read their &lt;a href="https://news.ycombinator.com/item?id=13048334"&gt;HN thread&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caviats&lt;/em&gt;: They don’t yet offer 2FA, but hopefully that should be fixed soon. Their spam filters aren’t the best either. Migadu even has a &lt;a href="https://www.migadu.com/procon/#the-drawbacks-list"&gt;Drawbacks&lt;/a&gt; section on their website that you &lt;em&gt;must read&lt;/em&gt; before signing up.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alternatives&lt;/em&gt;: RiseUp, FastMail.&lt;/p&gt;

&lt;h1 id="google-play-music"&gt;Google Play Music&lt;/h1&gt;

&lt;p&gt;I quite liked &lt;a href="https://music.google.com" title="Google Play Music"&gt;Google Play Music&lt;/a&gt;. While their subscription offering is horrible in India, I was a happy user of their “bring-your-own-music” plan. In fact, the most used Google service on my phone happened to be Google Play Music! I switched to a nice subsonic fork called [AirSonic][airsonic], which gives me the ability to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Listen on as many devices as I want (Google has some limits)&lt;/li&gt;
  &lt;li&gt;Listen using multiple clients at the same time&lt;/li&gt;
  &lt;li&gt;Stream at whatever bandwidth I pick (I stream at 64kbps over 2G networks!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m currently using &lt;a href="https://www.clementine-player.org/"&gt;Clementine&lt;/a&gt; on the Desktop (which unfortunately, doesn’t cache music), and &lt;a href="https://github.com/ultrasonic/ultrasonic/"&gt;UltraSonic&lt;/a&gt; on the phone. Airsonic even supports bookmarks, so listening to audiobooks becomes much more simpler.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: I didn’t like Google Play Music limits, plus I wanted to try the “phone-without-google” experiment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why AirSonic&lt;/em&gt;: &lt;a href="https://github.com/sindremehus/subsonic"&gt;Subsonic&lt;/a&gt; is now closed source, and the &lt;a href="https://www.reddit.com/r/selfhosted/comments/6saiac/airsonic_is_out/dlbea94/"&gt;Libresonic developers forked off to AirSonic&lt;/a&gt;, which is under active development. It is supports across all devices that I use, while &lt;a href="http://ampache.org/"&gt;Ampache&lt;/a&gt; has spotty Android support.&lt;/p&gt;

&lt;h1 id="google-keep"&gt;Google Keep&lt;/h1&gt;

&lt;p&gt;I switched across to &lt;a href="https://workflowy.com"&gt;WorkFlowy&lt;/a&gt;, which has both a Android and a Linux app (both based on webviews). I’ve used it for years, and it is a great tool. Moreover, I’m also using DAVDroid sync for Open Tasks app on my phone. Both of these work well enough offline.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: I didn’t use Keep much, and WorkFlowy is a far better tool anyway.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why WorkFlowy&lt;/em&gt;: It is &lt;em&gt;the best&lt;/em&gt; note-taking/list tool I’ve used.&lt;/p&gt;

&lt;h1 id="phone"&gt;Phone&lt;/h1&gt;

&lt;p&gt;I switched over to the &lt;a href="https://lineage.microg.org/"&gt;microG fork of lineageOS&lt;/a&gt; which offers a reverse-engineered implementation of the Google Play Services modules. It includes:&lt;/p&gt;

&lt;h2 id="microg-core"&gt;microG Core&lt;/h2&gt;

&lt;p&gt;Which talks to Google for Sync, Account purposes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: Saves me a lot of battery. I can uninstall this, unlike Google Play Services.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cons&lt;/em&gt;: Not all google services are supported very well. Push notifications have some issues on my phone. See the &lt;a href="https://github.com/microg/android_packages_apps_GmsCore/wiki/Implementation-Status"&gt;Wiki&lt;/a&gt; for Implementation Status.&lt;/p&gt;

&lt;h2 id="unifiedlp"&gt;UnifiedLP&lt;/h2&gt;

&lt;p&gt;Instead of the Google Location Provider. I use the Mozilla Location Services, along with Mozilla Stumbler to help improve their data.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: Google doesn’t need to know where I am.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caviats&lt;/em&gt;: GALP (Google Assisted Location Provider) does GPS locks much faster in comparision. However, I’ve found the Mozilla Location Services coverage in Bangalore to be pretty good.&lt;/p&gt;

&lt;h2 id="maps"&gt;Maps&lt;/h2&gt;

&lt;p&gt;Stil looking for decent alternatives.&lt;/p&gt;

&lt;h2 id="uber"&gt;Uber&lt;/h2&gt;

&lt;p&gt;microG comes with a Google Maps shim that talks to Open Street Maps. The maps feature on Uber worked fine with that shim, however booking cabs was not always possible. I switched over to &lt;code class="language-plaintext highlighter-rouge"&gt;m.uber.com&lt;/code&gt; which worked quite well for some time.&lt;/p&gt;

&lt;p&gt;Uber doesn’t really spend resources on their mobile site though, and it would ocassionaly stop working. Especially with regards to payments. I’ve switched over to the Ola mobile website, which works pretty well. I keep the OlaMoney app for recharging the OlaMoney wallet alongside.&lt;/p&gt;

&lt;p&gt;Uber-&amp;gt;Ola switch was also partially motivated by &lt;a href="https://www.theguardian.com/technology/2017/jun/18/uber-travis-kalanick-scandal-pr-disaster-timeline"&gt;how-badly-run Uber is&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="calendarcontacts"&gt;Calendar/Contacts&lt;/h2&gt;

&lt;p&gt;Most implementations support caldav/carddav for calendar/contacts sync. I’m using DAVDroid for syncing to a self-hosted &lt;a href="https://radicale.org" title="A Free and Open-Source CalDAV and CardDAV Server, runs on Python"&gt;Radicale Server&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: I’ve always had contacts synced to Google, so it was always my-single-source-of-truth for contacts. But since I’m on a different email provider now, it makes sense to move off those contacts as well. Radicale also lets me manage multiple addressbooks very easily.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why Radicale&lt;/em&gt;: I looked &lt;a href="https://github.com/Kickball/awesome-selfhosted#calendaring-and-contacts-management"&gt;around at alternatives&lt;/a&gt;, and 2 looked promising: Sabre.io, and Radicale. Sabre is no longer under development, so I picked Radicale, which also happened to have a &lt;a href="https://hub.docker.com/r/tomsquest/docker-radicale/"&gt;regularly updated docker image&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id="google-play-store"&gt;Google Play Store&lt;/h2&gt;

&lt;p&gt;Switch to &lt;a href="https://f-droid.org/"&gt;FDroid&lt;/a&gt; - It has some apps that &lt;a href="https://adaway.org/"&gt;Google doesn’t&lt;/a&gt; &lt;a href="https://newpipe.schabi.org/"&gt;like&lt;/a&gt;, and some more. Moreover, you can use YALP Store to download any applications from the Play Store. You can even run a FDroid repository for the apps you use from Play Store, as an alternative. See &lt;a href="https://shadow53.com/android/no-gapps/faq/can-i-use-the-official-play-store-with-microg/"&gt;this excellent&lt;/a&gt; guide on the various options.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: Play Store is tightly linked to Google Play Services, and doesn’t play nice with &lt;a href="https://microg.org/" title="MicroG is a free-as-in-freedom re-implementation of Google’s proprietary Android user space apps and libraries."&gt;microG&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why FDroid&lt;/em&gt;: FDroid has &lt;a href="https://f-droid.org/docs/Reproducible_Builds/?title=Deterministic,_Reproducible_Builds"&gt;publicly verifiable builds&lt;/a&gt;, and tons of open-source applications.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why Yalp&lt;/em&gt;: Was easy enough to setup.&lt;/p&gt;

&lt;p&gt;If you’re looking to migrate to MicroG, I’d recommend going through the entire &lt;a href="https://shadow53.com/android/no-gapps/setup-guide/microg/"&gt;NO Gapps Setup Guide&lt;/a&gt; by shadow53 before proceeding.&lt;/p&gt;

&lt;h1 id="lastpass"&gt;LastPass&lt;/h1&gt;

&lt;p&gt;I’ve switched to &lt;code class="language-plaintext highlighter-rouge"&gt;pass&lt;/code&gt; along with a sync to keybase.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt;: &lt;a href="https://en.wikipedia.org/wiki/LastPass#Security_issues"&gt;LastPass has had multiple breaches&lt;/a&gt;, and a plethora of security issues (including 2 RCE vulnerabilities). Their fingerprint authentication on Android could be bypassed til recently. &lt;em&gt;I just can’t trust them any more&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why pass&lt;/em&gt;: It is built on strong crypto primitives, is open-source, and has good integration with both &lt;a href="https://github.com/cdown/passmenu"&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;i3&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://github.com/browserpass/browserpass-extension"&gt;firefox&lt;/a&gt;. There is also a &lt;a href="https://git.zx2c4.com/password-store/tree/contrib/importers/lastpass2pass.rb"&gt;LastPass migration script&lt;/a&gt; that I used.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Caviats&lt;/em&gt;: Website names are used as filenames in pass, so even though passwords are encrypted, you don’t want to push it to a public Git server (since that would expose the list of services you are using). I’m using my &lt;a href="https://git.captnemo.in" title="Hosted by gitea, uptime not guaranteed"&gt;own git server&lt;/a&gt;, along with keybase git(which keeps it end-to-end encrypted, even branch names). You also need to be careful about your GPG keys, instead of a single master password.&lt;/p&gt;

&lt;h1 id="github"&gt;GitHub&lt;/h1&gt;

&lt;p&gt;For bonus, I setup a Gitea server hosted at &lt;a href="https://git.captnemo.in" title="Hosted by gitea, uptime not guaranteed"&gt;git.captnemo.in&lt;/a&gt;. &lt;a href="https://gitea.io/en-US/"&gt;Gitea&lt;/a&gt; is a fork of &lt;a href="https://gogs.io/"&gt;gogs&lt;/a&gt;, and is a single-binary go application that you can run easiy.&lt;/p&gt;

&lt;p&gt;Just running it for fun, since I’m pretty happy with my GitHub setup. However, I might move some of my sensitive repos (such as &lt;a href="https://github.com/captn3m0/dir-600l" title="Reverse engineered firmware for my D-Link 600L router"&gt;this&lt;/a&gt;) to my own host.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why Gitea&lt;/em&gt;: The other alternatives were &lt;code class="language-plaintext highlighter-rouge"&gt;gogs&lt;/code&gt;, and GitLab. There have been concerns about gogs development model, and GitLab was just too overpowered/heavy for my use case. (I’m using the home server for gaming as well, so it matters)&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;If you’re interested in my &lt;a href="/setup/homeserver/"&gt;self-hosting setup&lt;/a&gt;, I’m using Terraform + Docker, the code is hosted on &lt;a href="https://git.captnemo.in/nemo/nebula" title="If this is down, wait"&gt;the same server&lt;/a&gt;, and I’ve been writing about my experience and learnings:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="/blog/2017/09/17/home-server-build/"&gt;Part 1, Hardware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/11/09/home-server-update/"&gt;Part 2, Terraform/Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/18/home-server-learnings/"&gt;Part 3, Learnings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/31/migrating-from-google/"&gt;Part 4, Migrating from Google (and more)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2018/04/22/home-server-networking/"&gt;Part 5, Home Server Networking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2019/02/24/btrfs-raid-device-replacement-story/"&gt;Part 6, btrfs RAID device replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have any comments, &lt;a href="/contact/"&gt;reach out to me&lt;/a&gt;&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Sun, 31 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/12/31/migrating-from-google/</guid></item><item><title>Sourcing developer marketing content</title><link>/2017/12/28/Sourcing-developer-marketing-content/</link><description>&lt;p&gt;I spend a lot of time with dev tool and data companies. I think I&amp;rsquo;ve more or less banished myself to a life of working in the space, no consumer products for me. In that world a common topic that comes up amongst marketing teams is how do I get my team to contribute to content? Sometimes the person already has an idea of how they want the team to jump onto the bandwagon of their plan, sometimes they&amp;rsquo;re entirely open minded. I won&amp;rsquo;t get into pros and cons of various approaches here, rather after sharing some of my approaches in one on one settings I thought it could be useful to share more broadly here.&lt;/p&gt;
&lt;h3 id="turn-emails-into-blogs"&gt;
&lt;div&gt;
Turn emails into blogs
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m a big fan of high quality content when it comes to developer focused products. Yes, you can publish x vs. y with FUD and get some traction with it. You can publish high level customer stories that don&amp;rsquo;t get down into the details. But publishing high quality deep technical content that other engineers appreciate gives you a huge head start in getting buy in from your customers. The best thing about much of this type of content is you likely already have it sitting within your organization.&lt;/p&gt;
&lt;p&gt;Engineers spend a lot of time being thorough and articulate in their emails to their peers. If you see a well written email from one engineer to the engineers@ list and then others chime in either with questions, follow-up, or praise then it&amp;rsquo;s likely a great candidate for a blog post. We recently had one of these at Citus where another engineer replied with &amp;ldquo;Nice blog post :)&amp;rdquo;, a few weeks later we had &lt;a href="https://www.citusdata.com/blog/2017/12/22/distributed-count-vs-hyperloglog/"&gt;a post&lt;/a&gt; for the rest of the world to read.&lt;/p&gt;
&lt;p&gt;The thing about emails though is the engineers won&amp;rsquo;t usually take and turn them into a blog post. Get a technically minded person that likes to write and put some framing around it, pull out relevant details, and collaborate with the engineer. I&amp;rsquo;ve often found going from one of these emails to a fully published blog post can be anywhere from 2-8 hrs (including reviews and edits).&lt;/p&gt;
&lt;h3 id="beginner-mindset-with-tickets"&gt;
&lt;div&gt;
Beginner mindset with tickets
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;As your product people and engineers spend more and more time with the product they become numb to the cool feature from 2 years ago. That initial awe is just expected. Yes there are new advanced features and tech that is being built&amp;hellip; but most of your users aren&amp;rsquo;t the advanced power users. You still need to speak to the people just now onboarding and discovering you.&lt;/p&gt;
&lt;p&gt;The best way to maintain this beginner mindset is to capture the interactions with those that are newer to your product. Over the years I&amp;rsquo;ve made the practice of cataloging support tickets and the type of issue encountered. Any time the same issue is seen several times it becomes a candidate for a blog post or at the very least being clearly documented.&lt;/p&gt;
&lt;h3 id="make-sales-engineering-obsolete"&gt;
&lt;div&gt;
Make sales engineering obsolete
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Your sales engineers spend weeks with customers helping them implement complex solutions with your product. In a lot of cases they get really good at helping re-implement a similar solution over and over. Similar to your process with support tickets they&amp;rsquo;re a great source to take what they&amp;rsquo;ve done a few times over and turn it into a blog post.&lt;/p&gt;
&lt;p&gt;Usually after the first time implementing they have some ideas but there are rough edges. The second or third time they&amp;rsquo;ve helped a customer implement a particular approach it becomes a candidate for a post.&lt;/p&gt;
&lt;h3 id="training-and-documentation-dont-have-to-be-siloed"&gt;
&lt;div&gt;
Training and Documentation don&amp;rsquo;t have to be siloed
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m a big fan of not doing anything for one reason. You should absolutely document your product, and if you need to do training to support customers go for it. But that doesn&amp;rsquo;t mean those bits of content can&amp;rsquo;t be re-used. Documentation is a great place to take the factual how something works and then give it some narration of the end to end experience in a blog post.&lt;/p&gt;
&lt;h2 id="the-process"&gt;
&lt;div&gt;
The process
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re asking the question how do I get more good content out there, then you&amp;rsquo;re not leveraging the content you&amp;rsquo;re already sitting on top of. Though perhaps equal is getting a process in place. A few tips for that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t blanket ask to a list for volunteers, ask individuals and about specific posts. &lt;em&gt;If you see a great email, respond and ask if you can work with them to get it turned into a blog post&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll need to navigate the process, and make sure to have a process&lt;/li&gt;
&lt;li&gt;Separate messaging/flow from grammar&lt;/li&gt;
&lt;li&gt;My typical process is: outline -&amp;gt; draft -&amp;gt; feedback from 2-3 on draft -&amp;gt; finalize draft -&amp;gt; feedback from 4-5 (often some external parties) -&amp;gt; publish&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="whatd-i-miss"&gt;
&lt;div&gt;
What&amp;rsquo;d I miss?
&lt;/div&gt;
&lt;/h2&gt;
&lt;p&gt;Have other tips that are key to the process? Know of other places where content may already exist but isn&amp;rsquo;t being leveraged? Would love to &lt;a href="https://www.twitter.com/craigkerstiens"&gt;hear your thoughts&lt;/a&gt;.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Thu, 28 Dec 2017 22:55:56 GMT</pubDate><guid isPermaLink="true">/2017/12/28/Sourcing-developer-marketing-content/</guid></item><item><title>Top album picks for 2017</title><link>https://smcleod.net/2017/12/top-album-picks-for-2017/</link><description>&lt;p&gt;Here are my top album pics for 2017 (in no particular order)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This is by no means an exhaustive list, it&amp;rsquo;s just the top albums that really stood out to me and in all fairness, I&amp;rsquo;ve thought of several others since so there may be a follow up post (or two).&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="father-john-misty---pure-comedy"&gt;Father John Misty - &lt;a href="https://en.wikipedia.org/wiki/Pure_Comedy"&gt;Pure Comedy&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/albums_2017/FJM_PureComedy_Covers.gif?raw=true" /&gt;&lt;/p&gt;
&lt;p&gt;As a bonus, a short film was released with the album:&lt;/p&gt;
&lt;div style="padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
      
    &lt;/div&gt;

&lt;p&gt;From &lt;a href="https://en.wikipedia.org/wiki/Pure_Comedy"&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Thu, 28 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/12/top-album-picks-for-2017/</guid></item><item><title>HP 4951C Protocol Analyser</title><link>https://smcleod.net/2017/12/hp-4951c-protocol-analyser/</link><description>&lt;p&gt;My good friend Joel Shea received a most unlikely gift this Christmas - A vintage HP 4951 Protocol Analyser.&lt;/p&gt;
&lt;p&gt;According to the &lt;a href="http://www.hpmuseum.net/display_item.php?hw=1123"&gt;HP Computer Museum&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Original Price: $3595
The 4951B was replaced by the 4951C and 4952A in 1986. Both new models handled Async, BSC, SDLC, HDLC, X.25 and SNA protocols. The 4951C also handled DDCMP, while the 4952A did not. The 4952A handled X.21 while the 4951C did not. Both new analysers used a floppy dive (618 KB) for removable media.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Wed, 27 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/12/hp-4951c-protocol-analyser/</guid></item><item><title>Guidance on performing retrospectives</title><link>/2017/12/26/Guidance-on-performing-retrospectives/</link><description>&lt;p&gt;In my career I&amp;rsquo;ve had to conduct a number of retrospectives. Ahead of them it already sucked, there was an outage at some point, customers were impacted, and it was our fault. Never was it solely on our underlying infrastructure provider (AWS or Heroku), nope the blame was on us and we&amp;rsquo;d failed in some way. And as soon as the incident was resolved, it wasn&amp;rsquo;t time to go home and decompress with a beer, it was time start the process of a retrospective.&lt;/p&gt;
&lt;p&gt;Finding the motivation to get right back to work is tough, but not losing time is important. There is probably a lot out there on retrospectives, and in general I was well rehearsed at them. But since I&amp;rsquo;d not performed a large scale one in a few years I found myself rusty and thought it&amp;rsquo;d be good to share some of our process.&lt;/p&gt;
&lt;h3 id="capture-details-immediately"&gt;
&lt;div&gt;
Capture details immediately
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;It may not be clear if you&amp;rsquo;ve not been involved in many, but a retrospective is more than just a meeting to discuss what happened and how to fix it. It&amp;rsquo;s an overall process, it begins with capturing thorough details of what happened. The start is a timeline. The best thing to do is capture the details while they&amp;rsquo;re fresh. Start with a google doc and simply document the timeline of everything. Capture chat logs that are relevant while they&amp;rsquo;re fresh in history and easy to find.&lt;/p&gt;
&lt;p&gt;The start of an outage likely wasn&amp;rsquo;t the start of the timeline, there may have been something that happened days, weeks, or even years ago. Don&amp;rsquo;t just start from the time things went offline, go back to the causes as much as possible. If code was committed a year ago that was the offender make sure to note that.&lt;/p&gt;
&lt;h3 id="running-the-retrospective-the-meeting-part"&gt;
&lt;div&gt;
Running the retrospective (the meeting part)
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;There are a number of various good practices for running the retrospective itself. There are also a lot of different formats, all valid each with their own pros and cons. You can do with a basic timeline, what went well/didn&amp;rsquo;t, do a &lt;a href="https://en.wikipedia.org/wiki/5_Whys"&gt;five whys&lt;/a&gt; analysis. I tend to prefer a clean and dry analysis of timeline, what went well and what didn&amp;rsquo;t and what we&amp;rsquo;re doing about it.&lt;/p&gt;
&lt;p&gt;Some key tips to help a retrospective meeting be productive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explicitly set time bounds for each activity ahead of time, more so than maybe any other meeting it&amp;rsquo;s important to get through all your agenda. Hard time limits on the planned items is how you accomplish this.&lt;/li&gt;
&lt;li&gt;Spend at least some time on what went well, retrospectives aren&amp;rsquo;t fun. Spending some time on the good parts of your process and response isn&amp;rsquo;t wasted, just don&amp;rsquo;t be overly self-back-patting (that&amp;rsquo;s not a word but you get it).&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t discuss people, or rather don&amp;rsquo;t point fingers. Yes, people will come up, but it&amp;rsquo;s about the technical and process errors not the person that performed them.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="the-important-part"&gt;
&lt;div&gt;
The important part
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Every step in the retrospective is important, but the goal of them all is to get to how you can improve. With any retrospective there are likely two categories of improvements that will surface. The first is bugs that caused the issue or engineering that could go in place to help with the specific issue. The second are process improvements. If you don&amp;rsquo;t have improvements in both areas then spend more time thinking on the one you&amp;rsquo;re missing.&lt;/p&gt;
&lt;p&gt;Improvements shouldn&amp;rsquo;t be isolated to the exact issue you saw. Yes you may see the exact same issue again, but there is also a lot more you can draw out that helps improve overall quality. It&amp;rsquo;s inevitable you&amp;rsquo;ll see different issues in the future, thinking of how you can improve your systems and processes to catch those future issues is time well spent.&lt;/p&gt;
&lt;h3 id="sharing-the-details"&gt;
&lt;div&gt;
Sharing the details
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;ve done the hard work in the above, but it&amp;rsquo;s still good to share publicly and transparently. Within your public retrospective I tend to follow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Apologize, &lt;strong&gt;and mean it&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Show a firm understanding of your systems, and communicate the problem. Don&amp;rsquo;t try to be fancy technically, but don&amp;rsquo;t be too highlevel. Think goldilocks.&lt;/li&gt;
&lt;li&gt;Share what you&amp;rsquo;re doing to improve&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Credit to Mark for being the first person I&amp;rsquo;m aware of to lay it out like the above&lt;/em&gt;&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;&lt;em&gt;Thanks to &lt;a href="https://www.twitter.com/markimbriaco"&gt;Mark Imbriaco&lt;/a&gt;, &lt;a href="https://www.twitter.com/blakegentry"&gt;Blake Gentry&lt;/a&gt;, &lt;a href="https://www.twitter.com/danfarina"&gt;Daniel Farina&lt;/a&gt;, &lt;a href="https://www.twitter.com/lukasfittl"&gt;Lukas Fittl&lt;/a&gt;, &lt;a href="https://www.twitter.com/leinweber"&gt;Will Leinweber&lt;/a&gt; for input and feedback along the way.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Looking for more resources on the topic? Make sure to check out these two talks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.heavybit.com/library/video/every-minute-counts-coordinating-herokus-incident-response/"&gt;Every Minute Counts: Coordinating Heroku&amp;rsquo;s Incident Response&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vimeo.com/67178303"&gt;Monitorama 2013 - Mark Imbriaco&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Tue, 26 Dec 2017 22:55:56 GMT</pubDate><guid isPermaLink="true">/2017/12/26/Guidance-on-performing-retrospectives/</guid></item><item><title>Books I read in 2017</title><link>https://nindalf.com/posts/books-i-read-in-2017/</link><description>I share my top book recommendations for 2017, including Trevor Noah's Born a Crime and The Dictator's Handbook by Bruce Bueno de Mesquita and Alastair Smith.</description><author>Krishna's blog</author><pubDate>Mon, 25 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/books-i-read-in-2017/</guid></item><item><title>Man's Search for Meaning</title><link>https://nindalf.com/posts/mans-search-for-meaning/</link><description>Man's Search for Meaning offers a unique perspective on the Holocaust and introduces the theory of logotherapy.</description><author>Krishna's blog</author><pubDate>Sun, 24 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/mans-search-for-meaning/</guid></item><item><title>And Then There Were None</title><link>https://nindalf.com/posts/and-then-there-were-none/</link><description>A review of Agatha Christie's 'And Then There Were None' highlighting the absence of her typical detectives and the prevalence of casual racism in the 1930s.</description><author>Krishna's blog</author><pubDate>Wed, 20 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/and-then-there-were-none/</guid></item><item><title>Simply encrypt or decrypt a string using Boto3 Python and AWS KMS</title><link>https://boyter.org/2017/12/simply-encrypt-string-boto3-python-aws-kms/</link><description>&lt;p&gt;Another one of those things I need to look up every now and then. Below is a snippet of how to encrypt and decrypt a string using Python and KMS in AWS. The interesting thing is that you don&amp;rsquo;t need to supply the KMS key alias in the decryption portion. So long as whatever role or key you are using can access the key it should work. For the encryption you can either supply the full ARN of the key or the alias so long as you prefix it with alias/&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Mon, 18 Dec 2017 04:54:59 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/12/simply-encrypt-string-boto3-python-aws-kms/</guid></item><item><title>Learnings from building my own home server</title><link>https://captnemo.in/blog/2017/12/18/home-server-learnings/</link><description>&lt;h2 id="learnings"&gt;Learnings&lt;/h2&gt;

&lt;p&gt;I forgot to do this on the last blog post, so here is the list:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;archlinux has official packages for &lt;a href="https://wiki.archlinux.org/index.php/Microcode"&gt;intel-microcode-updates&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;wireguard is almost there. I’m running openvpn for now, waiting for the stable release.&lt;/li&gt;
  &lt;li&gt;While &lt;a href="https://traefik.io/"&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;traefik&lt;/code&gt;&lt;/a&gt; is great, I’m concerned about the security model it has for connecting to Docker (uses the docker unix socket over a docker mounted volume, which gives it root access on the host). Scary stuff.&lt;/li&gt;
  &lt;li&gt;Docker Labels are a great signalling mechanism. &lt;em&gt;Update&lt;/em&gt;: After seeing multiple bugs with how &lt;code class="language-plaintext highlighter-rouge"&gt;traefik&lt;/code&gt; uses docker labels, they have limited use-cases but work great in those. Don’t try to over-architect them for all your metadata.&lt;/li&gt;
  &lt;li&gt;Terraform still needs a lot of work on their docker provider. A lot of updates destroy containers, which should be applied without needing a destroy.&lt;/li&gt;
  &lt;li&gt;I can’t proxy gitea’s SSH authentication easily, since &lt;code class="language-plaintext highlighter-rouge"&gt;traefik&lt;/code&gt; doesn’t support TCP proxying yet.&lt;/li&gt;
  &lt;li&gt;The &lt;code class="language-plaintext highlighter-rouge"&gt;docker_volume&lt;/code&gt; resource in terraform is useless, since it doesn’t give you any control over the volume location on the host. (This might be a docker limitation.)&lt;/li&gt;
  &lt;li&gt;The &lt;code class="language-plaintext highlighter-rouge"&gt;upload&lt;/code&gt; block inside a &lt;code class="language-plaintext highlighter-rouge"&gt;docker_container&lt;/code&gt; resource is a great idea. Lets you push configuration straight inside a container. This is how I push configuration straight inside the &lt;code class="language-plaintext highlighter-rouge"&gt;traefik&lt;/code&gt; container for eg:
    &lt;div class="language-hcl highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="nx"&gt;upload&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${file("&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;traefik&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toml&lt;/span&gt;&lt;span class="s2"&gt;")}"&lt;/span&gt;
  &lt;span class="nx"&gt;file&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/etc/traefik/traefik.toml"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="advice"&gt;Advice&lt;/h2&gt;

&lt;p&gt;This section is if you’re venturing into a docker-heavy terraform setup:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Use &lt;code class="language-plaintext highlighter-rouge"&gt;traefik&lt;/code&gt;. Will save you a lot of pain with proxying requests.&lt;/li&gt;
  &lt;li&gt;Repeat the &lt;code class="language-plaintext highlighter-rouge"&gt;ports&lt;/code&gt; section for every IP you want to listen on. CIDRs don’t work.&lt;/li&gt;
  &lt;li&gt;If you want to run the container on boot, you want the following:
    &lt;div class="language-ini highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="py"&gt;restart&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;"unless-stopped"&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="py"&gt;destroy_grace_seconds&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="py"&gt;must_run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;If you have a single &lt;code class="language-plaintext highlighter-rouge"&gt;docker_registry_image&lt;/code&gt; resource in your state, you can’t run terraform without internet access.&lt;/li&gt;
  &lt;li&gt;Breaking your docker module into &lt;code class="language-plaintext highlighter-rouge"&gt;images.tf&lt;/code&gt;, &lt;code class="language-plaintext highlighter-rouge"&gt;volumes.tf&lt;/code&gt;, and &lt;code class="language-plaintext highlighter-rouge"&gt;data.tf&lt;/code&gt; (for registry_images) works quite well.&lt;/li&gt;
  &lt;li&gt;Memory limits on docker containers can be too contrained. Keep an eye on logs to see if anything is getting killed.&lt;/li&gt;
  &lt;li&gt;Setup Docker TLS auth &lt;em&gt;first&lt;/em&gt;. I tried proxying Docker over apache with basic auth, but it didn’t work out well.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="mongodb-with-forceful-server-restarts"&gt;MongoDB with forceful server restarts&lt;/h2&gt;

&lt;p&gt;Since my server gets a forceful restart every few days due to power-cuts (I’m still working on a backup power supply), I faced some issues with MongoDB being unable to recover cleanly. The lockfile would indicate a ungraceful shutdown, and it would require manual repairs, which sometimes failed.&lt;/p&gt;

&lt;p&gt;As a weird-hacky-fix, since most of the errors were from the MongoDB WiredTiger engine itself, I hypothesized that switching to a more robust engine might save me from these manual repairs. I switched to MongoRocks, and while it has stopped the issue with repairs, the wiki stil doesn’t like it, and I’m facing this issue: https://github.com/Requarks/wiki/issues/313&lt;/p&gt;

&lt;p&gt;However, I don’t have to repair the DB manually, which is a win.&lt;/p&gt;

&lt;h2 id="sshd-on-specific-interface"&gt;SSHD on specific Interface&lt;/h2&gt;

&lt;p&gt;My proxy server has the following&lt;/p&gt;

&lt;div class="language-plaintext highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;eth0 139.59.22.234
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And an associated Anchor IP for static IP usecases via Digital Ocean. (&lt;code class="language-plaintext highlighter-rouge"&gt;10.47.0.5&lt;/code&gt;, doesn’t show up in &lt;code class="language-plaintext highlighter-rouge"&gt;ifconfig&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;I wanted to run the following setup:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;eth0:22&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;sshd&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;Anchor-IP:22&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;simpleproxy&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;gitea:ssh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;where gitea is the git server hosting &lt;code class="language-plaintext highlighter-rouge"&gt;git.captnemo.in&lt;/code&gt;. This way:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;I could SSH to the proxy server over 22&lt;/li&gt;
  &lt;li&gt;And directly SSH to the Gitea server over 22 using a different IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unfortunately, &lt;code class="language-plaintext highlighter-rouge"&gt;sshd&lt;/code&gt; doesn’t allow you to listen on a specific interface, and since the &lt;code class="language-plaintext highlighter-rouge"&gt;eth0&lt;/code&gt; IP is non-static I can’t rely on it.&lt;/p&gt;

&lt;p&gt;As a result, I’ve resorted to just using 2 separate ports:&lt;/p&gt;

&lt;p&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;22&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;simpleproxy&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;gitea:ssh&lt;/code&gt;
&lt;code class="language-plaintext highlighter-rouge"&gt;222&lt;/code&gt; -&amp;gt; &lt;code class="language-plaintext highlighter-rouge"&gt;sshd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;There are some hacky ways around this by creating a new service that boots SSHD after network connectivity, but I thought this was much more stable.&lt;/p&gt;

&lt;h2 id="wikijs-public-pages"&gt;Wiki.js public pages&lt;/h2&gt;

&lt;p&gt;I’m using wiki.js setup at &lt;a href="https://wiki.bb8.fun"&gt;https://wiki.bb8.fun&lt;/a&gt;. A specific requirement I had was public pages, so that I could give links to people for specific resources that could be browser without a login.&lt;/p&gt;

&lt;p&gt;However, I wanted the default to be authenticated, and only certain pages to be public. The config for this was surprisingly simple:&lt;/p&gt;

&lt;h3 id="yaml-config"&gt;YAML config&lt;/h3&gt;

&lt;p&gt;You need to ensure that &lt;code class="language-plaintext highlighter-rouge"&gt;defaultReadAccess&lt;/code&gt; is false:&lt;/p&gt;

&lt;div class="language-yml highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;defaultReadAccess&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id="guest-access"&gt;Guest Access&lt;/h3&gt;

&lt;p&gt;The following configuration is set for the guest user:&lt;/p&gt;

&lt;p&gt;&lt;img alt="" src="/img/wiki.js-guest-access.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;Now any pages created under the &lt;code class="language-plaintext highlighter-rouge"&gt;/public&lt;/code&gt; directory are now browseable by anyone.&lt;/p&gt;

&lt;p&gt;Here is a sample page: &lt;a href="https://wiki.bb8.fun/public/nebula"&gt;https://wiki.bb8.fun/public/nebula&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="docker-ca-cert-authentication"&gt;Docker CA Cert Authentication&lt;/h2&gt;

&lt;p&gt;I wrote a script that goes with the docker TLS guide to help you setup TLS authentication&lt;/p&gt;



&lt;h2 id="openvpn-default-gateway-client-side-configuration"&gt;OpenVPN default gateway client side configuration&lt;/h2&gt;

&lt;p&gt;I’m running a OpenVPN configuration on my proxy server. Howver, I don’t always want to use my VPN as the default route, only when I’m in an untrusted network. I still however, want to be able to connect to the VPN and use it to connect to other clients.&lt;/p&gt;

&lt;p&gt;The solution is two-fold:&lt;/p&gt;

&lt;h3 id="server-side"&gt;Server Side&lt;/h3&gt;

&lt;p&gt;Make sure you &lt;em&gt;do not&lt;/em&gt; have the following in your OpenVPN &lt;code class="language-plaintext highlighter-rouge"&gt;server.conf&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;push "redirect-gateway def1 bypass-dhcp"&lt;/code&gt;&lt;/p&gt;

&lt;h3 id="client-side"&gt;Client Side&lt;/h3&gt;

&lt;p&gt;I created 2 copies of the VPN configuration files. Both of the them have identical config, except for this one line:&lt;/p&gt;

&lt;p&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;redirect-gateway def1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If I connect to the VPN config using this configuration, all my traffic is forwarded over the VPN. If you’re using Arch Linux, this is as simple as creating 2 config files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;/etc/openvpn/client/one.conf&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;/etc/openvpn/client/two.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And running &lt;code class="language-plaintext highlighter-rouge"&gt;systemctl start openvpn-client@one&lt;/code&gt;. I’ve enabled my non-defaut-route VPN service, so it automatically connects to on boot.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;If you’re interested in my &lt;a href="/setup/homeserver/"&gt;self-hosting setup&lt;/a&gt;, I’m using Terraform + Docker, the code is hosted on &lt;a href="https://git.captnemo.in/nemo/nebula/"&gt;the same server&lt;/a&gt;, and I’ve been writing about my experience and learnings:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="/blog/2017/09/17/home-server-build/"&gt;Part 1, Hardware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/11/09/home-server-update/"&gt;Part 2, Terraform/Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/18/home-server-learnings/"&gt;Part 3, Learnings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/31/migrating-from-google/"&gt;Part 4, Migrating from Google (and more)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2018/04/22/home-server-networking/"&gt;Part 5, Home Server Networking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2019/02/24/btrfs-raid-device-replacement-story/"&gt;Part 6, btrfs RAID device replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have any comments, &lt;a href="/contact/"&gt;reach out to me&lt;/a&gt;&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Mon, 18 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/12/18/home-server-learnings/</guid></item><item><title>Should I buy Bitcoin?</title><link>https://nindalf.com/posts/should-i-buy-bitcoin/</link><description>This article explores the question of whether or not to invest in Bitcoin, examining its value as a currency and asset, as well as its potential for future growth and stability.</description><author>Krishna's blog</author><pubDate>Mon, 11 Dec 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/should-i-buy-bitcoin/</guid></item><item><title>searchcode plexus</title><link>https://boyter.org/2017/12/searchcode-plexus/</link><description>&lt;h3 id="plexus-a-combination-of-interlaced-parts-a-network"&gt;Plexus &amp;ldquo;A combination of interlaced parts; a network.&amp;rdquo;&lt;/h3&gt;
&lt;p&gt;For a while I have been neglecting searchcode.com while working on searchcode server. This is of course not an ideal situation and as such I have started working on it again. The following is just a brief list of things I am considering, problems, issues etc…&lt;/p&gt;
&lt;p&gt;So back when I first started working on searchcode I wrote it using PHP. For searchcode next (the current version) I rewrote it using Python and Django. I had intented to continue using this stack for the forseeable future when I chose it. I quite like writing Python code and at the time the performance was acceptable. When I started writing searchcode server however I wanted to make it as easy to install as possible. The reason being that I considered it a competitive advantage to have users installing searchcode without any pain and be off and running. At the time I considered writing it in Go or Rust but had little experience with either language. I decided to pull on my sensible pants and chose Java which is a language I had worked with before and had excellent library support. With the 8th version Java had become considerably less painful to work with.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 05 Dec 2017 03:12:02 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/12/searchcode-plexus/</guid></item><item><title>Flutter for React Native Devs in 30 Seconds</title><link>https://www.swyx.io/flutter-for-react-native-devs-in-30-seconds-78g</link><description>You may have heard of Flutter, Google's answer to React Native. What should you know?</description><author>swyx's site RSS Feed</author><pubDate>Sun, 03 Dec 2017 18:06:18 GMT</pubDate><guid isPermaLink="true">https://www.swyx.io/flutter-for-react-native-devs-in-30-seconds-78g</guid></item><item><title>Serverless Machine Learning at Google</title><link>https://www.swyx.io/serverless-machine-learning-at-google-cp9</link><description>---</description><author>swyx's site RSS Feed</author><pubDate>Sun, 03 Dec 2017 00:25:33 GMT</pubDate><guid isPermaLink="true">https://www.swyx.io/serverless-machine-learning-at-google-cp9</guid></item><item><title>Are we human? Or are we reCAPTCHA?</title><link>https://www.swyx.io/are-we-human-or-are-we-recaptcha-blm</link><description>---</description><author>swyx's site RSS Feed</author><pubDate>Sat, 02 Dec 2017 23:49:06 GMT</pubDate><guid isPermaLink="true">https://www.swyx.io/are-we-human-or-are-we-recaptcha-blm</guid></item><item><title>Firebase Analytics in 30 Seconds</title><link>https://www.swyx.io/firebase-analytics-in-30-seconds-6pp</link><description>---</description><author>swyx's site RSS Feed</author><pubDate>Sat, 02 Dec 2017 22:57:12 GMT</pubDate><guid isPermaLink="true">https://www.swyx.io/firebase-analytics-in-30-seconds-6pp</guid></item><item><title>Medical Machine Learning in 30 Seconds</title><link>https://www.swyx.io/medical-machine-learning-in-30-seconds-dh1</link><description>---</description><author>swyx's site RSS Feed</author><pubDate>Sat, 02 Dec 2017 18:41:14 GMT</pubDate><guid isPermaLink="true">https://www.swyx.io/medical-machine-learning-in-30-seconds-dh1</guid></item><item><title>Adding Blog Here</title><link>https://benovermyer.com/blog/2017/11/adding-blog-here/</link><description>&lt;p&gt;I'm starting to use Hugo for blogging now. I might move all of the content currently on &lt;a href="https://pathfinder.space" rel="external"&gt;Pathfinder&lt;/a&gt; over to here, if it works as well as I hope it does.&lt;/p&gt;
&lt;p&gt;Also, I'm now hosting this site on Netlify, instead of deploying it myself to a VPS. This makes things much easier from a content management perspective.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Mon, 27 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2017/11/adding-blog-here/</guid></item><item><title>Ready Player One</title><link>https://nindalf.com/posts/ready-player-one/</link><description>Ready Player One is a fast-paced book filled with 80s references, but falls short with one-dimensional characters and a lack of new ideas.</description><author>Krishna's blog</author><pubDate>Sun, 26 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/ready-player-one/</guid></item><item><title>Six Easy Pieces</title><link>https://nindalf.com/posts/six-easy-pieces/</link><description>Six Easy Pieces by Richard Feynman is a fun read that provides an intuitive grasp of physics concepts, but falls short of teaching techniques.</description><author>Krishna's blog</author><pubDate>Thu, 23 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/six-easy-pieces/</guid></item><item><title>The Brothers Karamazov</title><link>https://nindalf.com/posts/the-brothers-karamazov/</link><description>The Brothers Karamazov by Fyodor Dostoevsky is a challenging but rewarding read, with richly detailed characters and authentic relationships.</description><author>Krishna's blog</author><pubDate>Sun, 19 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/the-brothers-karamazov/</guid></item><item><title>How to root Nexus 7 (2012) and flash it to LineageOS, from Mac OSX</title><link>http://blog.pythonaro.com/2017/11/how-to-root-nexus-7-2012-and-flash-it.html</link><description>I've finally got fed up enough with the old Nexus 7 (2012) that we originally bought to let the kids play - it's never really worked properly, getting laggy every 5 minutes and running out of battery after an hour. The kids moved on to an iPad, so I "installed" this crappy tablet to the kitchen wall, hoping to use it for calendaring and podcasts, but it was still horrendously laggy. I've decided to give a chance to LineageOS (previously CyanogenMod) to see if it helps. I'd be interested to know if anybody else uses a tablet wall-mounted in their kitchen, and what apps they installed - at the moment I have Paprika, the BBC players and weather, and PodcastAddict.&lt;br /&gt;
&lt;br /&gt;
Here are the full steps required for flashing - I write them here because some of these are at risk to disappear from the internet for good after the demise of CyanogenMod wiki.&lt;br /&gt;
&lt;br /&gt;
Note: &lt;b&gt;THIS WILL WIPE YOUR DEVICE, YOU WILL LOSE EVERYTHING THAT IS ON IT&lt;/b&gt; so first make backups etc etc.&lt;br /&gt;
&lt;br /&gt;
First you need to install the Android tools. I recommend doing this with &lt;a href="https://brew.sh/" target="_blank"&gt;homebrew&lt;/a&gt;, install it if you don't have it yet (it's extremely useful in many many cases).&lt;br /&gt;
Then open a terminal on your mac and type:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;brew tap caskroom/cask &lt;/li&gt;
&lt;li&gt;brew tap caskroom/versions&lt;/li&gt;
&lt;li&gt;brew cask install java8&lt;/li&gt;
&lt;li&gt;brew cask install android-sdk&lt;/li&gt;
&lt;/ul&gt;
Enable Developer Mode on the tablet by tapping 7 times on the build number under &lt;i&gt;Settings -&amp;gt; About tablet.&lt;/i&gt;&lt;br /&gt;
Back to Settings, tap on &lt;i&gt;Developer Options&lt;/i&gt; and enable USB Debug mode and Stay Awake.&lt;br /&gt;
Go back to your mac terminal and type:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;sudo adb start-server&lt;/li&gt;
&lt;/ul&gt;
This starts the android debugger server. &lt;br /&gt;
Connect the tablet with a real USB cable (beware charging-only cables! Those won't work.)&lt;br /&gt;
On the tablet screen, you should be prompted to authorize the device; do it.&lt;br /&gt;
Back to terminal:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;adb reboot bootloader&lt;/li&gt;
&lt;/ul&gt;
once the device comes back in bootloader mode:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;fastboot oem unlock&lt;/li&gt;
&lt;/ul&gt;
Accept the disclaimer on the tablet by clicking the power button when &lt;i&gt;Yes&lt;/i&gt; is highlighted (you can move with the volume buttons).&lt;br /&gt;
If it doesn't reboot on its own, select &lt;i&gt;Start&lt;/i&gt; (again with the power button). At this point you should see an unlocked pad at the bottom of the screen as Android loads.&lt;br /&gt;
Note: if you plan to flash another OS, there is no point in going through the whole setup at this point, skip as much as you can. &lt;br /&gt;
Re-enable Developer mode and USB Debugging.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;At this point the machine is rooted. &lt;/b&gt;The following steps are necessary only if you want to install LineageOS or other hacks; at the very minimum, though, you should install Trimmer (fstrim) from the Play store and use it liberally. Anyway, on with the flashing... &lt;br /&gt;
&lt;br /&gt;
Get the latest image for "grouper" from &lt;a href="https://twrp.me/"&gt;https://twrp.me/&lt;/a&gt;, and unzip it.&lt;br /&gt;
Back to the terminal:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;cd folder/where/you/have/your-downloaded-image.img&lt;/li&gt;
&lt;li&gt;fastboot flash recovery your-downloaded-image.img&lt;/li&gt;
&lt;li&gt;adb reboot bootloader&lt;/li&gt;
&lt;/ul&gt;
At this point you have a custom recovery image with a bunch of nifty features that make it very easy to hack the device. Tap Wipe and select system, cache, and dalvik.&lt;br /&gt;
Get the image you want to install. I'm currently trying &lt;a href="https://forum.xda-developers.com/nexus-7/development/rom-lineageos-14-1-nexus-7-2012-t3530261" target="_blank"&gt;this&lt;/a&gt; but in general anything after CM10 / Android 4.1 may be on the slow side for the original Nexus. You probably want the Google Apps from opengapps.org - choose ARM / 7.1 and the Micro option. Save both the apps zip and the image zip in the same folder.&lt;br /&gt;
Back to Terminal, let's copy these files to the device:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;cd folder/where/you/have/your/zips&lt;/li&gt;
&lt;li&gt;adb push your-downloaded-image.zip /&lt;/li&gt;
&lt;li&gt;adb push your-downloaded-gapps.zip /&lt;/li&gt;
&lt;/ul&gt;
On the tablet, in the recovery screen, select Install, tap on Install ZIP, then select the image file and install. Repeat for the gapps file. If gapps refuse to go in because of space constraints, download &lt;a href="https://www.androidfilehost.com/?fid=745425885120692225" target="_blank"&gt;this file&lt;/a&gt;, rename it &lt;i&gt;gapps-config.txt&lt;/i&gt;, then copy it to the device in the same location as the gapps zip:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;adb push gapps-config.txt /&lt;/li&gt;
&lt;/ul&gt;
and try again to install the gapps image. &lt;ul&gt;
&lt;/ul&gt;
Reboot the tablet. You might have to re-enable developer mode and usb debugging.&lt;br /&gt;
Install the &lt;a href="https://play.google.com/store/apps/details?id=com.fifthelement.trimmer" target="_blank"&gt;Trimmer (fstrim)&lt;/a&gt; app, which is absolutely necessary. Launch it and click Trim Now. Click on the settings icon and enable autotrim as frequently as possible. In fact, every time you install an app or write a bunch of files, before you launch the new app, open Trimmer and do a trim, or it will all get laggy again.&lt;br /&gt;
Another good app is &lt;a href="https://play.google.com/store/apps/details?id=com.icecoldapps.sshserver&amp;amp;hl=en" target="_blank"&gt;Android SSH Server&lt;/a&gt;, although it's a bit old it still works fine and it's easy to configure. You just have to use the options &lt;i&gt;-t -oHostKeyAlgorithms=+ssh-dss -p XXXXX&lt;/i&gt; (where XXXXX is the custom port configured in the app, Android won't allow the classic one) when connecting.&lt;br /&gt;
&lt;i&gt;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
And that's it.</description><author>Subclassed</author><pubDate>Fri, 17 Nov 2017 02:56:59 GMT</pubDate><guid isPermaLink="true">http://blog.pythonaro.com/2017/11/how-to-root-nexus-7-2012-and-flash-it.html</guid></item><item><title>Talk - Clustered, Distributed File and Volume Storage with GlusterFS</title><link>https://smcleod.net/2017/11/talk-clustered-distributed-file-and-volume-storage-with-glusterfs/</link><description>&lt;p&gt;Using GlusterFS to provide volume storage to Kubernetes as a replacement for our existing file and static content hosting.&lt;/p&gt;
&lt;p&gt;This talk was given at &lt;a href="https://www.meetup.com/Infrastructure-Coders/events/244535588/"&gt;Infracoders&lt;/a&gt; on Tuesday 14th November 2017.&lt;/p&gt;
&lt;p&gt;Click below to view slides (PDF version):
&lt;a href="https://media.githubusercontent.com/media/sammcj/smcleod_files/refs/heads/master/slides/lightning_san.pdf"&gt;&lt;img alt="Click to view slides" src="https://smcleod.net//img/gluster-first-slide.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://media.githubusercontent.com/media/sammcj/smcleod_files/refs/heads/master/slides/lightning_san.pdf"&gt;&lt;em&gt;Direct download link&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/gluster_talk_14112017/2.jpg?raw=true" /&gt;
&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/gluster_talk_14112017/3.jpg?raw=true" /&gt;
&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/gluster_talk_14112017/4.jpg?raw=true" /&gt;
&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/gluster_talk_14112017/5.jpg?raw=true" /&gt;
&lt;img src="https://github.com/sammcj/smcleod_files/blob/master/images/gluster_talk_14112017/6.jpg?raw=true" /&gt;&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Tue, 14 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/11/talk-clustered-distributed-file-and-volume-storage-with-glusterfs/</guid></item><item><title>Running terraform and docker on my home server</title><link>https://captnemo.in/blog/2017/11/09/home-server-update/</link><description>&lt;p&gt;The last time I’d posted about my Home Server build in September, I’d just gotten it working. Since then, I’ve made a lot of progress. It is now running almost 10 services, up from just Kodi back then. Now it has a working copy of:&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;&lt;a href="https://kodi.tv/"&gt;Kodi&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;I was running &lt;code class="language-plaintext highlighter-rouge"&gt;kodi-standalone-service&lt;/code&gt;, set to run on boot, as per the &lt;a href="https://wiki.archlinux.org/index.php/Kodi#Kodi-standalone-service"&gt;ArchLinux Wiki&lt;/a&gt;, but switched in favor of openbox to a simple autorun.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="http://store.steampowered.com/linux"&gt;Steam&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;The current setup uses Steam as the application launcher. This lets me ensure that the Steam Controller works across all applications.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="http://openbox.org/wiki/Main_Page"&gt;Openbox&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Instead of running Kodi on xinit, I’m now running openbox with autologin against a non-privileged user.&lt;/dd&gt;
  &lt;dt&gt;PulseAudio&lt;/dt&gt;
  &lt;dd&gt;I tried fighting it, but it was slightly easier to configure compared to dmix. Might move to dmix if I get time.&lt;/dd&gt;
  &lt;dt&gt;btrfs&lt;/dt&gt;
  &lt;dd&gt;I now have the following disks:
    &lt;ol&gt;
      &lt;li&gt;128GB root volume. (Samsung EVO-850)&lt;/li&gt;
      &lt;li&gt;1TB volume for data backups&lt;/li&gt;
      &lt;li&gt;3TB RAID0 configuration across 2 disks.
There are some btrfs subvolumes in the 3TB raid setup, including one specifically for docker volumes. The docker guide recommends running btrfs subvolumes on the block device, which I didn’t like, so I’m running docker volumes in normal mode on a btrfs disk. I don’t have enough writes to care much yet, but might explore this further.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://www.docker.com/"&gt;Docker&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;This has been an interesting experiment. Kodi is still installed natively, but I’ve been trying to run almost everything else as a docker container. I’ve managed to do the configuration entirely via terraform, which has been a great learning experience. I’ve found terraform much more saner as a configuration system compared to something like ansible, which gets quite crazy. (We have a much more crazy terraform config at work, though).&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://www.terraform.io/"&gt;Terraform&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;I have a private repository on GitLab called &lt;code class="language-plaintext highlighter-rouge"&gt;nebula&lt;/code&gt; which I use as the source of truth for the configuration. It doesn’t hold everything yet, just the following:
    &lt;ol&gt;
      &lt;li&gt;Docker Configuration (not the docker service, just the container/volumes)&lt;/li&gt;
      &lt;li&gt;CloudFlare - I’m using &lt;code class="language-plaintext highlighter-rouge"&gt;bb8.fun&lt;/code&gt; as the root domain, which is entirely managed using the CloudFlare terraform provider.&lt;/li&gt;
      &lt;li&gt;MySQL - Running a MariaDB container, which has been configured by-hand till &lt;a href="https://github.com/hashicorp/go-version/pull/34"&gt;this PR gets merged&lt;/a&gt;.&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/go-gitea/gitea"&gt;Gitea&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Running as a docker container, provisioned using terraform. Plan to proxy this using &lt;code class="language-plaintext highlighter-rouge"&gt;git.captnemo.in&lt;/code&gt;.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://emby.media/"&gt;Emby&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Docker Container. Nothing special. Plan to set this up as the Kodi backend.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://couchpota.to/"&gt;Couchpotato&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Experimental setup for now. Inside a docker container.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://flexget.com/"&gt;Flexget&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;I wish I knew how to configure this. Also inside docker.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://traefik.io/"&gt;traefik&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Running as a simple reverse proxy for most of the above services&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="http://elibsrv.sourceforge.net/"&gt;elibsrv&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;A simple OPDS server, which I use against my Kindle. If you don’t know what OPDS is, you should [check this out][]. Running on a simple apache setup on the archlinux box for now. WIP for dockerization.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://vaemendis.net/ubooquity/"&gt;ubooquity&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Simple ebook server. Proxied over the internet. Has a online ebook reader, which is pretty cool.&lt;/dd&gt;
  &lt;dt&gt;MariaDB&lt;/dt&gt;
  &lt;dd&gt;I set this up planning to shift Kodi’s data to this, but now that I have emby setup - I’m not so sure. Still, keeping this running for now.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://transmissionbt.com/"&gt;Transmission&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Hooked up to couchpotato,flexget, and sickrage so it can do things.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://sickrage.github.io/"&gt;Sickrage&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;Liking this more than flexget so far, much more easier to configure and use.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://airsonic.github.io/"&gt;AirSonic&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;This is the latest fork of libresonic, which was itself forked off subsonic. My attempt at getting off Google Play Music.&lt;/dd&gt;
&lt;/dl&gt;

&lt;h2 id="learnings"&gt;Learnings&lt;/h2&gt;

&lt;p&gt;Moved these to a separate &lt;a href="/blog/2017/12/18/home-server-learnings/"&gt;blog post&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="todo"&gt;TODO&lt;/h2&gt;

&lt;p&gt;A few things off my TODO list:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Create a Docker image for elibsrv that comes with both &lt;code class="language-plaintext highlighter-rouge"&gt;ebook-convert&lt;/code&gt; and &lt;code class="language-plaintext highlighter-rouge"&gt;kindlegen&lt;/code&gt; pre-installed&lt;/li&gt;
  &lt;li&gt;&lt;del&gt;Do the same for ubooquity as well&lt;/del&gt; (Using the &lt;code class="language-plaintext highlighter-rouge"&gt;linuxserver/ubooquity&lt;/code&gt; docker image)&lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;p&gt;If you’re interested in my &lt;a href="/setup/homeserver/"&gt;self-hosting setup&lt;/a&gt;, I’m using Terraform + Docker, the code is hosted on &lt;a href="https://git.captnemo.in/nemo/nebula/"&gt;the same server&lt;/a&gt;, and I’ve been writing about my experience and learnings:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="/blog/2017/09/17/home-server-build/"&gt;Part 1, Hardware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/11/09/home-server-update/"&gt;Part 2, Terraform/Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/18/home-server-learnings/"&gt;Part 3, Learnings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/31/migrating-from-google/"&gt;Part 4, Migrating from Google (and more)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2018/04/22/home-server-networking/"&gt;Part 5, Home Server Networking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2019/02/24/btrfs-raid-device-replacement-story/"&gt;Part 6, btrfs RAID device replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have any comments, &lt;a href="/contact/"&gt;reach out to me&lt;/a&gt;&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Thu, 09 Nov 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/11/09/home-server-update/</guid></item><item><title>Postgres - the non-code bits</title><link>/2017/10/31/Postgres-the-non-code-bits/</link><description>&lt;p&gt;Postgres is an interesting open source project. It&amp;rsquo;s truly one of a kind, it has its own license to prove it as opposed to falling under something like Apache or GPL. The Postgres community structure is something that is pretty well defined if you&amp;rsquo;re involved in the community, but to those outside it&amp;rsquo;s likely a little less clear. In case you&amp;rsquo;re curious to learn more about the community here&amp;rsquo;s a rundown of a few various aspects of it:&lt;/p&gt;
&lt;h3 id="postgresql-license"&gt;
&lt;div&gt;
PostgreSQL License
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with the legal part first. &lt;em&gt;First IANAL&lt;/em&gt;. PostgreSQL is under its own license. For those who don&amp;rsquo;t regularly follow software licensing it&amp;rsquo;s extremely liberal and flexible. You can take Postgres, fork it, change it, package it up, and resell it. This is actually one of the reasons you see Postgres at the core of so many other databases like Par Accel, Asterdata, etc. That and that it&amp;rsquo;s such a solid code base that is capable of being extended. &lt;em&gt;I once heard someone describe how they don&amp;rsquo;t really like writing C, but they enjoy writing Postgres C ;)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;A thing you can&amp;rsquo;t do is profit off the PostgreSQL logo without any approval from the core team.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="the-people"&gt;
&lt;div&gt;
The people
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Within the Postgres community there are 2 major sets of people.&lt;/p&gt;
&lt;h3 id="the-core-team"&gt;
&lt;div&gt;
The core team
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The core team is a smaller team within the Postgres community. The core team is effectively a &lt;a href="https://www.postgresql.org/developer/core/"&gt;steering committee&lt;/a&gt; for Postgres. They&amp;rsquo;re responsible for coordinating releases, handling confidential issues (read: security issues), managing permissions around PostgreSQL code and infrastructure, defining policy.&lt;/p&gt;
&lt;p&gt;The core team is a very small list of people, at the moment 5 individuals.&lt;/p&gt;
&lt;h3 id="contributors"&gt;
&lt;div&gt;
Contributors
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Yes, anyone can contribute to Postgres, and with each release there are a laundry of people that write some code that goes into Postgres. If fact Postgres 10 had &lt;a href="https://www.postgresql.org/docs/current/static/release-10.html#idm46046833759776"&gt;325 people&lt;/a&gt; that contributed in some form. That said there is a hierarchy that exists. The two biggest ones are committers and major contributors.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Committers&lt;/strong&gt; gain access after years of contributing to Postgres showing sustained commitment to the project. New committers are voted on each year at PgCon which happens in March/April in Ottawa. If you&amp;rsquo;re ever curious for a conference of what&amp;rsquo;s coming and being deep in the internals of Postgres it&amp;rsquo;s one to check out. Once you do gain your commit bit you&amp;rsquo;re expected to contribute every couple of years to the project. And of course there are a &lt;a href="https://wiki.postgresql.org/wiki/Committers"&gt;number of qualifications&lt;/a&gt; such as contributing high quality code and perhaps most key is helping review others contributions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Major contributors&lt;/strong&gt; are another notable group. Major contributors don&amp;rsquo;t have full sole commit access, but are held in a higher regard from consistently contributing major features as well as providing review for others.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contributors&lt;/strong&gt; in general are another area worth calling out. While they may not have a flagship feature to their name like the major contributors, Postgres is what it is because of the contributions of everyone.&lt;/p&gt;
&lt;h3 id="postgresql-the-company"&gt;
&lt;div&gt;
PostgreSQL the company
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Well, it turns out there isn&amp;rsquo;t a company behind Postgres, it&amp;rsquo;s one thing that makes it unique–no one can ever &amp;ldquo;own it&amp;rdquo;. There are some official PostgreSQL non-profits though in particular the US non-profit and the EU non-profit. These non-profits ensure that the core guidelines are enforced and also give coverage for the community to help put on official community conferences. A few of these happen each year which include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.pgcon.org/2018/"&gt;PGCon&lt;/a&gt; - The hackers conference&lt;/li&gt;
&lt;li&gt;&lt;a href="https://2017.postgresopen.org/"&gt;PostgresOpen SV&lt;/a&gt; - A consolidation of PostgresOpen and PGConf Silicon Valley&lt;/li&gt;
&lt;li&gt;&lt;a href="https://postgresopen.org/"&gt;PGConf EU&lt;/a&gt; - The largest PG European Conference which moves around each year&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;re looking for a way to support the PostgreSQL non-profit organization I&amp;rsquo;d encourage you to consider joining &lt;a href="https://postgresql.us/"&gt;PostgreSQL.us&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="engaging"&gt;
&lt;div&gt;
Engaging
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;So you want to jump into the community, where do you even start? The first place I&amp;rsquo;d encourage is to subscribe to the &lt;a href="https://www.postgresql.org/list/"&gt;mailing list&lt;/a&gt; or check out the &lt;a href="http://postgres-slack.herokuapp.com/"&gt;slack channel&lt;/a&gt;. The users mailing is a great one to just jump in and help answer questions and see what people need help with. The hackers list is where you go to get a peek at all the fun debates/discussions/development.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re thinking about contributing it&amp;rsquo;s a good idea to lurk on the hackers list for a bit first. Then when the commitfest comes chip in and help review some patches and do some testing. Oh and of course, you can always blog about what you&amp;rsquo;re doing with Postgres and will aim to get it included into &lt;a href="https://www.postgresweekly.com"&gt;Postgres Weekly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re looking for a deeper resource on Postgres I recommend the book &lt;a href="https://theartofpostgresql.com/?affiliate=cek"&gt;The Art of PostgreSQL&lt;/a&gt;. It is by a personal friend that has aimed to create the definitive guide to Postgres, from a developer perspective. If you use code CRAIG15 you&amp;rsquo;ll receive 15% off as well.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Tue, 31 Oct 2017 22:55:56 GMT</pubDate><guid isPermaLink="true">/2017/10/31/Postgres-the-non-code-bits/</guid></item><item><title>Born to Run</title><link>https://nindalf.com/posts/born-to-run/</link><description>Born to Run is a low-quality pseudo-science book that pushes the agenda of barefoot running without disclosing the lack of conclusive evidence.</description><author>Krishna's blog</author><pubDate>Tue, 31 Oct 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/born-to-run/</guid></item><item><title>Applying syntax in Sublime based on the first file line</title><link>https://smcleod.net/2017/10/applying-syntax-in-sublime-based-on-the-first-file-line/</link><description>&lt;p&gt;In vim, you can add a comment at the top of files to set the syntax, e.g.:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="chroma" tabindex="0"&gt;&lt;code class="language-shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# vim: syntax=ruby&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In SublimeText there are &lt;em&gt;many&lt;/em&gt; ways to detect syntax, one interesting approach I&amp;rsquo;ve recently found useful is to match on the top line in the file.
For example, with Puppet there is a file called &lt;code&gt;Puppetfile&lt;/code&gt;, it has no extension but it&amp;rsquo;s really Ruby syntax, so it&amp;rsquo;s useful to add linting incase you
miss something simple like a &lt;code&gt;,&lt;/code&gt; and break deployments.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Wed, 25 Oct 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/10/applying-syntax-in-sublime-based-on-the-first-file-line/</guid></item><item><title>How to build waifu2x command-line version on osx</title><link>http://blog.pythonaro.com/2017/07/how-to-build-waifu2x-command-line.html</link><description>&lt;div&gt;&lt;b&gt;UPDATE 23/10/2017:&lt;/b&gt; recent changes seem to be incompatible with clang. I have updated the steps below to check out the last commit that is known as working. &lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://waifu2x.udp.jp/index.html" target="_blank"&gt;Waifu2x&lt;/a&gt; is a popular image converter backed by neural-network models, typically used to upscale images from &lt;i&gt;anime&lt;/i&gt;. The various web versions are easy to use but typically don't allow for batch-processing, because it's a relatively intensive operation. However, there is a command-line version that is fairly easy to compile on Windows and Linux. OSX support was notably absent... until now.&lt;/div&gt;
&lt;div&gt;
These are the steps required to get it working on Mac:
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;brew tap science &amp;amp;&amp;amp; brew install opencv3&lt;/code&gt;&lt;br /&gt;(if you don't have &lt;a href="https://brew.sh/" target="_blank"&gt;Homebrew&lt;/a&gt;, go install it now - it's wonderful)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git clone https://github.com/DeadSix27/waifu2x-converter-cpp.git&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd waifu2x-converter-cpp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git checkout d69313040b0784662465fb1d2eca81a2b1ebccb2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cmake -DOVERRIDE_OPENCV=1 -DOPENCV_PREFIX=/usr/local/Cellar/opencv3/&amp;lt;your version here&amp;gt; .&lt;/code&gt; (remember the dot at the end!)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make -j4&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
At this point, you have the executable &lt;code&gt;waifu2x-converter-cpp&lt;/code&gt; in the directory; you can &lt;code&gt;make install&lt;/code&gt; if you really want to (I prefer to keep custom stuff in my home dir). To test it's working, the following command should return info on your system:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;./waifu2x-converter-cpp --list-processor&lt;/code&gt;
&lt;/div&gt;
&lt;br /&gt;
If you need some images to test, &lt;a href="https://imgur.com/gallery/dSpHk" target="_blank"&gt;here&lt;/a&gt; you can get quite a few stills from the gorgeous 5 Centimeters Per Second. Note: you might have to rename the folder "models_rgb" into "models" before converting.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
BONUS: Qt GUI&lt;/h3&gt;
&lt;div&gt;
If you hate the command-line, there is &lt;a href="https://github.com/toyg/waifu2x-converter-qt" target="_blank"&gt;a simple QT wrapper&lt;/a&gt;. To compile it you will need Qt-Creator and Qt installed and configured. This used to be very complicated, but both items have now been packaged for Homebrew so it's all awesomely simple (well, compared to what it was, at least). Note that you still have to do the steps above - the wrapper needs the waifu2x executable to be already compiled.&lt;/div&gt;
&lt;br /&gt;
&lt;h4&gt;
Install and configure Qt and Qt-Creator&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;brew install qt &amp;amp;&amp;amp; brew cask install qt-creator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Launch &lt;i&gt;Qt Creator &lt;/i&gt;from Launchpad, then go to &lt;i&gt;Qt Creator -&amp;gt; Preferences&lt;/i&gt; (Command + ,)&lt;/li&gt;
&lt;li&gt;Select &lt;i&gt;Build &amp;amp; Run&lt;/i&gt;, then the &lt;i&gt;Qt Versions&lt;/i&gt; tab&lt;/li&gt;
&lt;li&gt;Click on &lt;i&gt;Add...&lt;/i&gt; and select “Macintosh HD”&lt;/li&gt;
&lt;li&gt;Press Command + Shift + . to show hidden directories&lt;/li&gt;
&lt;li&gt;select &lt;code&gt;/usr/local/Cellar/qt5/&amp;lt;your version&amp;gt;/bin/qmake&lt;/code&gt; then OK and OK again to close the Preferences window&lt;/li&gt;
&lt;li&gt;Reopen &lt;i&gt;Preferences -&amp;gt; Build &amp;amp; Run&lt;/i&gt;, select the Kits tab and click Add&lt;/li&gt;
&lt;li&gt;Set the following options:
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;Name&lt;/i&gt; to something like "Qt CLang Desktop"&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Both &lt;i&gt;Compiler&lt;/i&gt; options to Clang X86 64bit&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Qt Version&lt;/i&gt; to the version you just created&lt;/li&gt;
&lt;li&gt;Click on &lt;i&gt;Make Default&lt;/i&gt; then OK to close Preferences.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
Compile waifu2x-converter-qt&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git clone https://github.com/toyg/waifu2x-converter-qt.git&lt;/code&gt; (&lt;a href="https://github.com/khws4v1/waifu2x-converter-qt"&gt;the original repo&lt;/a&gt; looks abandoned, so I forked it and tweaked it a bit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd waifu-converter-qt &amp;amp;&amp;amp; open waifu2x-converter-qt.pro&lt;/code&gt; (this should open Qt Creator; if it doesn't, launch it manually and &lt;i&gt;File -&amp;gt; Open Project&lt;/i&gt; -&amp;gt; select the .pro file).&lt;/li&gt;
&lt;li&gt;Select &lt;i&gt;Build -&amp;gt; Run&lt;/i&gt; (or Command + R). The resulting .app bundle should now be in a folder called &lt;code&gt;build-waifu2x-converter-qt-&amp;lt;something something&amp;gt;&lt;/code&gt;, just beside your main project folder.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
When you first launch the GUI, you should probably go to Preferences and set the path to your waifu2x-converter-cpp executable.&lt;/div&gt;</description><author>Subclassed</author><pubDate>Mon, 23 Oct 2017 05:49:54 GMT</pubDate><guid isPermaLink="true">http://blog.pythonaro.com/2017/07/how-to-build-waifu2x-command-line.html</guid></item><item><title>Static Analysis: It's Simply Critical</title><link>https://donatstudios.com/StaticAnalysis</link><description>&lt;p&gt;I am someone who spends large portions of their time working in weakly typed languages. Namely, PHP and JavaScript. I argue that static analysis is a &lt;strong&gt;must-have&lt;/strong&gt; when working with any weakly typed language. It is nearly impossible to make reliable code without it. &lt;/p&gt;
&lt;p&gt;Static analysis makes up for the missing type system and allows you to scale.&lt;/p&gt;
&lt;p&gt;I recently got in an argument with another developer over static analysis. It's been an ongoing point of contention. He was angry that code that &lt;em&gt;works fine&lt;/em&gt; but didn't document its undetectable return types was failing CI. He argued that if the code works, it should pass. He argued that if the code works, it is &amp;quot;correct&amp;quot;.&lt;/p&gt;
&lt;p&gt;I put forward the exact opposite position. Code that &lt;em&gt;works&lt;/em&gt; but doesn't &lt;em&gt;statically analyze&lt;/em&gt; is incorrect. Code that is &lt;strong&gt;correct&lt;/strong&gt; has no potential of runtime error. &lt;/p&gt;
&lt;p&gt;My intentions are not only to sell you on the idea that you should be statically analyzing your code, but to convince you that it is fundamental to responsible reliable development.&lt;/p&gt;
&lt;p&gt;Humans are fallible; code written by humans doubly so. By it's very nature that code is broken until &lt;strong&gt;proven otherwise.&lt;/strong&gt; If it cannot be statically analyzed, it &lt;strong&gt;cannot be&lt;/strong&gt; &lt;strong&gt;proven&lt;/strong&gt; correct.&lt;/p&gt;
&lt;p&gt;If code &lt;strong&gt;runs&lt;/strong&gt; as expected, this only proves it correct in the &lt;em&gt;limited scope&lt;/em&gt; it's been ran it within. Be that ones, tens or even hundreds of thousands of parameter combinations, it's always limited. There therefore &lt;strong&gt;must&lt;/strong&gt; be zero expectation of it continuing to work.&lt;/p&gt;
&lt;p&gt;To the contrary, if code statically analyzes unerring, it will run without runtime error in &lt;strong&gt;all&lt;/strong&gt; &lt;strong&gt;cases&lt;/strong&gt;, save a failure of the analyzer. This code &lt;strong&gt;is proven&lt;/strong&gt;. This code is &lt;strong&gt;correct&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Code which &amp;quot;works&amp;quot; does nothing to prove that it's used as you expect. In particular elsewhere within the project. It does nothing to prove it will remain correctly used in all cases in the future.&lt;/p&gt;
&lt;p&gt;I know what you are thinking &amp;quot;But… but… my code runs correctly within my expected domain&amp;quot;, and that's fine. That is what's expected of it. But throw exceptions if it happen it doesn't know how to handle, things that creep outside the expected domain. It lets the future developers, the analyzer, and the program itself know the intended domain and when it steps outside it. &lt;/p&gt;
&lt;p&gt;No amount of fuzz testing can account for another developer doing something you never expected.&lt;/p&gt;
&lt;p&gt;To give a trivial but near real life example, consider the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getUserById( userId ) {
    if(userId &amp;gt; 0) {
        return new User($userId);
    }

    return null;
}

var user = getUserById( input.value );
console.log( "Hello userId: " + user.getId() );&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above code may work throughout &lt;strong&gt;all&lt;/strong&gt; your testing. Every place you use it, every time you try it, everything your application throws at it - success. &lt;/p&gt;
&lt;p&gt;This code &lt;strong&gt;works&lt;/strong&gt;, and yet this code &lt;strong&gt;is broken.&lt;/strong&gt; This code does not handle the potential &lt;strong&gt;null,&lt;/strong&gt; and has the potential to trigger a runtime error. This code has the capability of a runtime error, and is therefore &lt;strong&gt;incorrect&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Making this code &lt;strong&gt;correct&lt;/strong&gt; would be as simple as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var user = getUserById( input.value );

if(!user instanceof User) {
    throw new Error("User not found");
}

console.log( "Hello userId: " + user.getId() );&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An Exception, as opposed to a runtime error, is something the code and coder anticipates. It's an easy way to show you've thought about the domain of your code. Even unhandled, it's clear the developer considered the possibility. It's easily recoverable. Throwing an exception here is &lt;strong&gt;correct&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Obviously you'd probably want to handle that Error in the example somewhere, but that's outside the scope of this writing.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The trivial case above is reasonably obvious and easy to spot. Let's instead imagine the function to get a user is deep in your codebase. While we are at it, let's also say that the logical &lt;code&gt;User|null&lt;/code&gt; union we've created gets passed around. Passed several levels deep, rather than using it immediately where it's fetched. It rapidly becomes &lt;em&gt;much&lt;/em&gt; less obvious, nigh impossible, to notice that there is an issue. A call 8 methods deep has no idea it might be receiving a null. This is &lt;strong&gt;exactly&lt;/strong&gt; the kind of thing a static analysis is for.&lt;/p&gt;
&lt;p&gt;A static analyzer knows the full scope and range of possible values. It is able to pinpoint problems a human fails to notice. Noting all function calls within the scope of a project and knowing all possible.&lt;/p&gt;
&lt;p&gt;All this withstanding, static analysis cannot prove the logic is correct. That's not what static analysis is for. Unit tests and other testing prove that. Static analysis proves that the code itself executes free of unhandled &lt;strong&gt;runtime errors&lt;/strong&gt;. It &lt;strong&gt;is&lt;/strong&gt; the &lt;strong&gt;type checker your language forgot&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Arguable the better solution is to switch to a type safe language; one with compile time type checks and ideally union types. That's not always an option for most people though, consider the recent meteoric growth of JavaScript. &lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; is without a doubt the best option for JavaScript. I highly recommend it — consider it static analysis on steroids. It's JavaScript with the addition of strong typing. There's no reason to be writing straight JavaScript anymore. TypeScript is really a wonderful all in one solution.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://elm-lang.org/"&gt;Elm&lt;/a&gt; is a neat alternative but a completely different paradigm. While it compiles to JavaScript, it's completely foreign and more of an all-in situation. It borrows much of its syntax from Haskell, and offers the aforementioned union types. &lt;/p&gt;
&lt;p&gt;For PHP on the other hand I recommend a handful of tools. &lt;a href="https://scrutinizer-ci.com/"&gt;Scrutinizer&lt;/a&gt; is in my experience the most &lt;em&gt;feature complete&lt;/em&gt; of the hosted CI services. I make extensive use of &lt;a href="https://github.com/squizlabs/PHP_CodeSniffer"&gt;PHP CodeSniffer&lt;/a&gt; which is an amazing tool based around a PHP tokenizer. It's a lot of fun writing your own sniffs in my experience. I have begun experimenting with &lt;a href="https://github.com/phan/phan"&gt;Phan&lt;/a&gt; - it's a little unforgiving, in a good way… And of course &lt;a href="https://blog.jetbrains.com/phpstorm/"&gt;PHPStorm&lt;/a&gt; has a pretty decent analyzer built in.&lt;/p&gt;</description><author>Donat Studios</author><pubDate>Sat, 21 Oct 2017 10:59:24 GMT</pubDate><guid isPermaLink="true">https://donatstudios.com/StaticAnalysis</guid></item><item><title>Born a Crime</title><link>https://nindalf.com/posts/born-a-crime/</link><description>'Born a Crime' by Trevor Noah is a hilarious and thought-provoking memoir about his childhood in South Africa.</description><author>Krishna's blog</author><pubDate>Thu, 19 Oct 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/born-a-crime/</guid></item><item><title>BBQ with a Dutch ICT/start up Delegation</title><link>https://boyter.org/2017/10/bbq-dutch-ictstart-delegation/</link><description>&lt;p&gt;So a few weeks back I received an interesting email that at first thought looked like a scam.&lt;/p&gt;
&lt;p&gt;In short I was being invited to a BBQ at the Consul General&amp;rsquo;s residence in Sydney to meet an ICT/start up delegation from the Netherlands. Let me straight up say I have no idea why I would receive something like this. I am not dutch, have no dutch ancestry (that I am aware of) and while &lt;a href="https://searchcode.com"&gt;searchcode.com&lt;/a&gt; somehow is listed on the &lt;a href="http://www.startupranking.com/top/australia"&gt;top startups in Sydney&lt;/a&gt; somehow its not as though it has lots of press coverage or is a real start-up (its more a hobby side business at the moment).&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 17 Oct 2017 03:22:18 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/10/bbq-dutch-ictstart-delegation/</guid></item><item><title>The Crusades: The Authoritative History of the War for the Holy Land</title><link>https://nindalf.com/posts/the-crusades/</link><description>Discover the truth about the Crusades and why invoking them today is misguided, in this well-researched and engaging book.</description><author>Krishna's blog</author><pubDate>Tue, 17 Oct 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/the-crusades/</guid></item><item><title>Broadcom, Or How I Learned To Start Worrying And Drop The Packet</title><link>https://smcleod.net/2017/10/broadcom-or-how-i-learned-to-start-worrying-and-drop-the-packet/</link><description>&lt;p&gt;&lt;img src="https://smcleod.net/2017/10/broadcom-or-how-i-learned-to-start-worrying-and-drop-the-packet/office-space-broadcom.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Earlier this week we started the process to upgrade one of our hypervisor compute clusters when we encountered a rather painful bug with HP&amp;rsquo;s Broadcom NIC chipsets.&lt;/p&gt;
&lt;p&gt;We were part way through a routine rolling pool upgrade of our hypervisor (XenServer) cluster when we observed unexpected and intermittent loss of connectivity between several VMs, then entire XenServer hosts.&lt;/p&gt;
&lt;p&gt;The problems appeared to impact hosts that hadn&amp;rsquo;t yet upgraded to XenServer 7.2. We now attribute this to a symptom of extreme packet loss between the hosts in the pool and thanks to buggy firmware from Broadcom and HP.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Fri, 13 Oct 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/10/broadcom-or-how-i-learned-to-start-worrying-and-drop-the-packet/</guid></item><item><title>Dear Postgres</title><link>/2017/10/12/Dear-Postgres/</link><description>&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;Dear Postgres,&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always felt an affinity for you in my 9 years of working with you. I know others have known you longer, but that doesn&amp;rsquo;t mean they love you more. Years ago when others complained about your rigidness or that you weren&amp;rsquo;t as accommodating as others I found solace in your steadfast values:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Don&amp;rsquo;t lose data&lt;/li&gt;
&lt;li&gt;Adhere to standards&lt;/li&gt;
&lt;li&gt;Move forward with a balancing act between new fads of the day while still continuously improving&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;ve been there and seen it all. Years ago you were being disrupted by XML databases. As companies made heavy investment into what such a document database would do for their organization you proceeded to &amp;ldquo;simply&amp;rdquo; add a datatype that accomplished the same and brought your years of progress along with it.&lt;/p&gt;
&lt;p&gt;In the early years you had the standard format of index &lt;em&gt;b-tree&lt;/em&gt; that most database engines leveraged. Then quietly but confidently you started adding more. Then came K-nearest neighbor, generalized inverted indexes (GIN), and generalized search-tree (GiST), only to be followed by space partitioned GiST and block range indexes (BRIN). Now the only question is which do I use?&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;All the while there was this other camp using for something that felt cool but outside my world: GIS. GIS, geographical information systems, I thought was something only civil engineers used. Then GPS came along, then the iPhone and location based devices came along and suddenly I wanted to find out the nearest path to my Peets, or manage geographical region for my grocery delivery service. PostGIS had been there all along building up this powerful feature set, sadly to this day I still mostly marvel from the sideline at this whole other feature set I long to take advantage of&amp;hellip; &lt;em&gt;one day&amp;hellip; one day&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A little over 5 years ago I fell in love with your fastly improving analytical capabilities. No you weren&amp;rsquo;t an MPP system yet, but here came window functions and CTEs, then I almost understood recursive CTEs &lt;em&gt;(still working on that one)&lt;/em&gt;. I can iterate over data in a recursive fashion without PL/PgSQL? Yes please! I only want to use it more.&lt;/p&gt;
&lt;p&gt;And then five years ago, document stores start taking over the world. I feel like I&amp;rsquo;ve seen this story before, wasn&amp;rsquo;t XML going to change the internet? Enter JSON, the JSON datatype, and JSONB. Wow, this is really nice to mix relational, document storage, join against things. I suddenly don&amp;rsquo;t get why more don&amp;rsquo;t take this flexible approach to building on a good foundation and layering on the refinements.&lt;/p&gt;
&lt;p&gt;Extensions! Where have you been all my life? There’s &lt;a href="https://www.citusdata.com"&gt;Citus&lt;/a&gt;, and &lt;a href="https://github.com/aggregateknowledge/postgresql-hll"&gt;HyperLogLog&lt;/a&gt;, and &lt;a href="https://www.zombodb.com/"&gt;ZomboDB&lt;/a&gt;, with each I can add functionality to Postgres without it being limited to the standard release, they can be in C or not. Wait, all along so much has been built on this foundation? PostGIS, full-text search, hstore? I like all those things, why didn&amp;rsquo;t you tell me all along about this foundation? Postgres, I like what I&amp;rsquo;m seeing how you&amp;rsquo;re allowing others to do more without having it be in the core of Postgres. This extension stuff is really kinda cool that it&amp;rsquo;s Postgres and then some, kinda like C and then ++, wait nevermind scratch that analogy.&lt;/p&gt;
&lt;p&gt;Sorry, I&amp;rsquo;ve rambled a bit. You&amp;rsquo;re a little over twenty years old now. I&amp;rsquo;ve known you for nearly ten of those years so I know there&amp;rsquo;s so much about your background I don&amp;rsquo;t know, I hope we get to spend the time together to share it all. This 10 release is really an exciting one to me. We&amp;rsquo;ve spent all this time together and I feel like each passing year the bond grows fonder.&lt;/p&gt;
&lt;p&gt;Now you&amp;rsquo;ve brought me better parallelism so I can further utilize my system resources. I now have partitioning. Thank you! I don&amp;rsquo;t have to roll my own hacks to help age out old data for my time series database. Logical replication will make so many other things possible, such as more online upgrades and integration with other systems.&lt;/p&gt;
&lt;p&gt;Postgres, I just want to say thank you for the past ten years together. Thank you for all you’ve done and for all you’ll continue to do in the future.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re looking for a deeper resource on Postgres I recommend the book &lt;a href="https://theartofpostgresql.com/?affiliate=cek"&gt;The Art of PostgreSQL&lt;/a&gt;. It is by a personal friend that has aimed to create the definitive guide to Postgres, from a developer perspective. If you use code CRAIG15 you&amp;rsquo;ll receive 15% off as well.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Thu, 12 Oct 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/10/12/Dear-Postgres/</guid></item><item><title>Fighting Cliqz in Firefox</title><link>http://blog.pythonaro.com/2017/10/fighting-cliqz-in-firefox.html</link><description>&lt;p&gt;Mozilla recently &lt;a href="https://news.ycombinator.com/item?id=15421708" target="_blank"&gt;announced&lt;/a&gt; that some of their German users downloading Firefox will receive a version that tracks some of their web activity, reporting it to Cliqz.com. In the wake of this development, which is pretty awful from a privacy perspective, I went spelunking into my version of FF to see if anything had been enabled already in my build.&lt;/p&gt;
&lt;p&gt;To my horror, cliqz.com is already mentioned in a few places, despite me never installing anything related to it. If you enter about:config in the address bar and search for cliqz, a few entries will pop up:&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHiy5bih0NwTag1vZ-vAKmLACHGqdC7SDoLJBZlT3-qfqW72OgrwctwAx1Np9FTSQbtwjJ41EozdgEB3SCFs2wRiYOTyGt5czrePuR0rMsaFRd_YgIbAXAIl9xKPS5DYU1bfDF/s1600/Screen+Shot+2017-10-10+at+13.29.39.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHiy5bih0NwTag1vZ-vAKmLACHGqdC7SDoLJBZlT3-qfqW72OgrwctwAx1Np9FTSQbtwjJ41EozdgEB3SCFs2wRiYOTyGt5czrePuR0rMsaFRd_YgIbAXAIl9xKPS5DYU1bfDF/s640/Screen+Shot+2017-10-10+at+13.29.39.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
Straight out of the gate, it looks like something from cliqz.com has been whitelisted. What is it?&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;social.*&lt;/code&gt; preferences are related to &lt;a href="https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Social_API"&gt;SocialAPI&lt;/a&gt; Services, a sort of framework to integrate social networks into Firefox. It was introduced several years ago but very few people actually use it or know about it. If you look up the related preferences, a few more entries are present:&lt;br /&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA14GIChGnQ4FM2JfySiFinLc0GXEzsGnTAXTl5qrn4tn7ce7giPyo61N5fY-gx2OpMOLtO-I72iFC2skSbQlukA6HmgroxBCyLVvrX3diRQWEcR38Y5Qqi5YwovCgvyS-dDY1/s1600/Screen+Shot+2017-10-10+at+13.32.15.png" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiA14GIChGnQ4FM2JfySiFinLc0GXEzsGnTAXTl5qrn4tn7ce7giPyo61N5fY-gx2OpMOLtO-I72iFC2skSbQlukA6HmgroxBCyLVvrX3diRQWEcR38Y5Qqi5YwovCgvyS-dDY1/s640/Screen+Shot+2017-10-10+at+13.32.15.png" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
If you are a fan of this sort of thing, you can go to that address &lt;a href="https://activations.cdn.mozilla.net/"&gt;https://activations.cdn.mozilla.net&lt;/a&gt; and install some of the available providers. I have no idea whether they still work or not; among others, delicious.com has recently been sold and it's in read-only mode, so that's unlikely to be useful.&lt;/p&gt;
&lt;p&gt;I personally disabled it all (that &lt;code&gt;social.remote-install.enabled&lt;/code&gt; freaked me out) by double-clicking all boolean properties (turning them to false) and double-clicking then clearing out social.whitelist.&lt;/p&gt;
&lt;p&gt;The other mentions of cliqz seem to be special-casing whitelists aimed at making an extension work around some of the recent changes in the Firefox extensibility framework. If I understand correctly, &lt;code&gt;dom.ipc.cpows.allow-cpows-in-compat-addons&lt;/code&gt; allows Cross-Process Object Wrappers (an internal communication mechanism that should slowly be removed) to be used even if the extension is marked as compatible with the new multiprocess architecture; and &lt;code&gt;extensions.legacy.exceptions&lt;/code&gt; exempts the listed extensions from being marked as Legacy.&lt;/p&gt;
&lt;p&gt;In those whitelists, there is one called testpilot@cliqz.com. &lt;a href="https://testpilot.firefox.com/"&gt;Test Pilot&lt;/a&gt; is an official Firefox add-on from Mozilla that will periodically publish some proposed additions to the browser, allowing users to enable them, test them out, give feedback and so on. I personally like it, some of the proposed features are actually pretty good (although it doesn't look like any of them ever made it to the main build); considering its complexity (an extension-installing extension) it makes sense that it might require some special privileges, and after all it's an official Mozilla feature so why not?&lt;/p&gt;
&lt;p&gt;Well, it looks like Mozilla is using cliqz.com to gather remote info about TestPilot usage, which is very disappointing. TestPilot was marketed as an official Mozilla project, there was no mention of third parties involved. I won't disable TestPilot, but I am again very disappointed in their cavalier attitude with my usage data.&lt;/p&gt;
&lt;p&gt;To conclude, it looks like the "synergy" between Mozilla and Cliqz was already underway before the latest announcement. It's likely that more defensive hacks will be required in the near future to keep user-tracking at bay in Firefox. As a long-time fan of Mozilla since the '90s, this development is disappointing.&lt;/p&gt;</description><author>Subclassed</author><pubDate>Tue, 10 Oct 2017 16:18:31 GMT</pubDate><guid isPermaLink="true">http://blog.pythonaro.com/2017/10/fighting-cliqz-in-firefox.html</guid></item><item><title>The Remains of the Day</title><link>https://nindalf.com/posts/the-remains-of-the-day/</link><description>Follow the story of a reserved butler as he reflects on his life and the meaning of his work in The Remains of the Day.</description><author>Krishna's blog</author><pubDate>Sat, 07 Oct 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/the-remains-of-the-day/</guid></item><item><title>Computers Have Had Emotions for Quite Some Time</title><link>https://svedic.org/philosophy/computers-have-had-emotions-for-quite-some-time</link><description>A common assumption is that computers can’t have emotions. But there is a strong philosophical argument that AI systems have had emotions for many decades now. Before making an argument, we need to define &amp;#8220;emotion&amp;#8221;. That definition shouldn’t require consciousness &amp;#8230; &lt;a href="https://svedic.org/philosophy/computers-have-had-emotions-for-quite-some-time"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><author>Svedic.org</author><pubDate>Fri, 29 Sep 2017 23:31:52 GMT</pubDate><guid isPermaLink="true">https://svedic.org/philosophy/computers-have-had-emotions-for-quite-some-time</guid></item><item><title>Do Androids Dream of Electric Sheep</title><link>https://nindalf.com/posts/do-androids-dream-of-electric-sheep/</link><description>Do Androids Dream of Electric Sheep has potential, but is sidetracked by a confusing premise and missed opportunities.</description><author>Krishna's blog</author><pubDate>Fri, 29 Sep 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://nindalf.com/posts/do-androids-dream-of-electric-sheep/</guid></item><item><title>Kernel Recipes 2017 day 3 notes</title><link>https://anisse.astier.eu/kernel-recipes-2017-day-3.html</link><description>&lt;p&gt;This is continuation of &lt;a href="kernel-recipes-2017-day-1.html"&gt;day 1&lt;/a&gt; and &lt;a href="kernel-recipes-2017-day-2.html"&gt;day 2&lt;/a&gt; of Kernel Recipes 2017.&lt;/p&gt;
&lt;h1&gt;Using Linux &lt;code&gt;perf&lt;/code&gt; at Netflix&lt;/h1&gt;
&lt;p&gt;by Brendan Gregg&lt;/p&gt;
&lt;p&gt;Brendan started with a ZFS on Linux case study, where it was eating 30% of the CPU resources, which it should never be doing.  He started by generating a …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Fri, 29 Sep 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/kernel-recipes-2017-day-3.html</guid></item><item><title>Kernel Recipes 2017 day 2 notes</title><link>https://anisse.astier.eu/kernel-recipes-2017-day-2.html</link><description>&lt;p&gt;This is continuation of &lt;a href="kernel-recipes-2017-day-1.html"&gt;yesterday's live blog&lt;/a&gt; of Kernel Recipes 2017.&lt;/p&gt;
&lt;h1&gt;Linux Kernel Self Protection Project&lt;/h1&gt;
&lt;p&gt;by Kees Cook&lt;/p&gt;
&lt;p&gt;&lt;a href="http://outflux.net/slides/2017/kr/kspp.pdf"&gt;Presentation slides&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The aim of the project is more than protecting the kernel.&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;Kees' motivation for working on Linux, is the two billion Android devices running a Linux. The majority …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Thu, 28 Sep 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/kernel-recipes-2017-day-2.html</guid></item><item><title>Kernel Recipes 2017 day 1 live-blog</title><link>https://anisse.astier.eu/kernel-recipes-2017-day-1.html</link><description>&lt;p&gt;Following &lt;a href="kernel-recipes-2016-notes.html"&gt;last year attempt&lt;/a&gt;, I'm doing a live blog of Kernel Recipes 6th edition. There's also a &lt;a href="https://air.mozilla.org/embedded-recipes-27-sept-morning/"&gt;live stream at Air Mozilla&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;What's new in the world of storage for Linux&lt;/h1&gt;
&lt;p&gt;by Jens Axboe&lt;/p&gt;
&lt;p&gt;Jens started with the status of blk-mq conversions: most drivers are now converted: stec, nbd, MMC …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Wed, 27 Sep 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/kernel-recipes-2017-day-1.html</guid></item><item><title>Embedded Recipes 2017 notes</title><link>https://anisse.astier.eu/embedded-recipes-2017-live-blog.html</link><description>&lt;p&gt;Following &lt;a href="kernel-recipes-2016-notes.html"&gt;last year attempt&lt;/a&gt;, I'm doing a live blog of Embedded Recipes 1st edition.&lt;/p&gt;
&lt;p&gt;&lt;img alt="jpg" src="/images/er2017/01-Anne.jpg" /&gt;&lt;/p&gt;
&lt;h1&gt;Understanding SCHED_DEADLINE&lt;/h1&gt;
&lt;p&gt;by Steven Rostedt&lt;/p&gt;
&lt;p&gt;Every task starts as SCHED_OTHER, where each task gets a fair share of the CPU bandwidth.&lt;/p&gt;
&lt;p&gt;Then comes SCHED_FIFO, where it's first in, first out, a task will run until it …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Tue, 26 Sep 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/embedded-recipes-2017-live-blog.html</guid></item><item><title>GlusterFS</title><link>https://smcleod.net/2017/09/glusterfs/</link><description>&lt;p&gt;We&amp;rsquo;re in the process of shifting from using our custom &amp;lsquo;glue&amp;rsquo; for orchestrating Docker deployments to Kubernetes, When we first deployed Docker to replace LXC and our legacy Puppet-heavy application configuration and deployment systems there really wasn&amp;rsquo;t any existing tool to manage this, thus we rolled our own, mainly a few Ruby scripts combined with a Puppet / Hiera / Mcollective driven workflow.&lt;/p&gt;
&lt;p&gt;The main objective is to replace our legacy NFS file servers used to host uploads / attachments and static files for our web applications, while NFS(v4) performance is adequate, it is a clear single point of failure and of course, there are the age old stale mount problems should network interruptions occur.&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Mon, 25 Sep 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/09/glusterfs/</guid></item><item><title>Return Of The RSS</title><link>https://smcleod.net/2017/09/return-of-the-rss/</link><description>&lt;p&gt;Of all the tools for reading news and subscribing to software releases, I still find RSS the most useful.&lt;/p&gt;
&lt;p&gt;I use Feedly to manage my rss subscriptions and keep all my devices in sync, but instead of using the Feedly&amp;rsquo;s own client, I use an app called Reeder as the client / reader itself.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://feedly.com/smcleod/blogs"&gt;Link: My Feedly RSS Feed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="feedly"&gt;&lt;a href="https://feedly.com"&gt;Feedly&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;RSS feed subscription management&lt;/p&gt;
&lt;p&gt;Features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keyword alerts.&lt;/li&gt;
&lt;li&gt;Browser plugins to subscribe to (current) url.&lt;/li&gt;
&lt;li&gt;Notation and highlighting support (a bit like Evernote).&lt;/li&gt;
&lt;li&gt;Search and filtering across large numbers of feeds / content.&lt;/li&gt;
&lt;li&gt;IFTTT, Zapier, Buffer and Hootsuite integration.&lt;/li&gt;
&lt;li&gt;Built in save / share functionality (that I only use when I&amp;rsquo;m on the website).&lt;/li&gt;
&lt;li&gt;Backup feeds to Dropbox.&lt;/li&gt;
&lt;li&gt;Very fast, regardless of the fact that I&amp;rsquo;m in Australia - which often impacts the performance of apps / sites that tend to be hosted on AWS in the US as the latency is so high.&lt;/li&gt;
&lt;li&gt;Article de-duplication is currently being developed I believe, so I&amp;rsquo;m looking forward to that!&lt;/li&gt;
&lt;li&gt;Easy manual import, export and backup (no vendor lock-in is important to me).&lt;/li&gt;
&lt;li&gt;Public sharing of your Feedly feeds (we&amp;rsquo;re getting very meta here!).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="reeder"&gt;&lt;a href="http://reederapp.com"&gt;Reeder&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A (really) beautiful and fast iOS / macOS client&lt;/p&gt;</description><author>smcleod.net</author><pubDate>Fri, 22 Sep 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://smcleod.net/2017/09/return-of-the-rss/</guid></item><item><title>Tracking and managing your Postgres connections</title><link>/2017/09/18/postgres-connection-management/</link><description>&lt;p&gt;Managing connections in Postgres is a topic that seems to come up several times a week in conversations. I&amp;rsquo;ve written some about scaling your connections and the right approach when you truly need a high level of connections, which is to use a connection pooler like pgBouncer. But what do you do before that point and how can you better track what is going on with your connections in Postgres?&lt;/p&gt;
&lt;p&gt;Postgres under the covers has a lot of metadata about both historical and current activity against a system. Within Postgres you can run the following query which will give you a few results:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;count&lt;/span&gt;(&lt;span style="color: #f92672;"&gt;*&lt;/span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #66d9ef;"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; pg_stat_activity
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;GROUP&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;BY&lt;/span&gt; &lt;span style="color: #ae81ff;"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #66d9ef;"&gt;count&lt;/span&gt; &lt;span style="color: #f92672;"&gt;|&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;-------+-------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;&lt;/span&gt; &lt;span style="color: #ae81ff;"&gt;7&lt;/span&gt; &lt;span style="color: #f92672;"&gt;|&lt;/span&gt; active
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #ae81ff;"&gt;69&lt;/span&gt; &lt;span style="color: #f92672;"&gt;|&lt;/span&gt; idle
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #ae81ff;"&gt;26&lt;/span&gt; &lt;span style="color: #f92672;"&gt;|&lt;/span&gt; idle &lt;span style="color: #66d9ef;"&gt;in&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;transaction&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #ae81ff;"&gt;11&lt;/span&gt; &lt;span style="color: #f92672;"&gt;|&lt;/span&gt; idle &lt;span style="color: #66d9ef;"&gt;in&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;transaction&lt;/span&gt; (aborted)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;(&lt;span style="color: #ae81ff;"&gt;4&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;rows&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;Time: &lt;span style="color: #ae81ff;"&gt;30&lt;/span&gt;.&lt;span style="color: #ae81ff;"&gt;337&lt;/span&gt; ms
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each of these is useful in determining what you should do to better manage your connection count. All of these numbers can be useful to record every say 30 seconds and chart on your own internal monitoring. Lets break down each:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;active&lt;/strong&gt; - This is currently running queries, in a sense this is truly how many connections you may require at a time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;idle&lt;/strong&gt; - This is where you have opened a connection to the DB (most frameworks do this and maintain a pool of them), but nothing is happening. This is the one area that a connection pooler like pgBouncer can most help.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;idle in transaction&lt;/strong&gt; - This is where your app has run a &lt;code&gt;BEGIN&lt;/code&gt; but it&amp;rsquo;s now waiting somewhere in a transaction and not doing work.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For &lt;strong&gt;idle&lt;/strong&gt; as mentioned above it&amp;rsquo;s one that you do want to monitor and if you see a high number here it&amp;rsquo;s worth investing in setting up a pgBouncer.&lt;/p&gt;
&lt;p&gt;For &lt;strong&gt;idle in transaction&lt;/strong&gt; this one is a bit more interesting. Here what you likely want to do when first investigating is get an idea of how old those are. You can do this by querying pg_stat_activity and filtering for where the state is &lt;code&gt;idle in transaction&lt;/code&gt; and checking how old those queries are. For ones that have been running too long you may want to manually kill them.&lt;/p&gt;
&lt;p&gt;If you find that you have some stale transactions hanging around this could be for days, hours, or even just a few minutes you may want to set a default to kill those transactions.&lt;/p&gt;
&lt;p&gt;To help with this Postgres has a nice feature of a &lt;code&gt;statement_timeout&lt;/code&gt;. A statement timeout will automatically kill queries that run longer than the allotted time. You can set this at both a global level and for a specific session. To do this at the database level you&amp;rsquo;d run this with an &lt;code&gt;alter database dbnamehere set statement_timeout = 60000;&lt;/code&gt; which is 60 seconds. To do so during a given session simply run &lt;code&gt;set statment_timeout = 6000000;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For &lt;em&gt;idle in transaction&lt;/em&gt; that have been running too long there is its own setting setting that you can set in a similar fashion &lt;code&gt;idle_in_transaction_session_timeout&lt;/code&gt; (on Postgres 9.6 and up). Setting both &lt;code&gt;statement_timeout&lt;/code&gt; and &lt;code&gt;idle_in_transaction_session_timeout&lt;/code&gt; will help with cancelling long running queries and transactions.&lt;/p&gt;
&lt;p&gt;Keeping your connection limits in check should lead to a much healthier performing database and thus app.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re looking for a deeper resource on Postgres I recommend the book &lt;a href="https://theartofpostgresql.com/?affiliate=cek"&gt;The Art of PostgreSQL&lt;/a&gt;. It is by a personal friend that has aimed to create the definitive guide to Postgres, from a developer perspective. If you use code CRAIG15 you&amp;rsquo;ll receive 15% off as well.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Mon, 18 Sep 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/09/18/postgres-connection-management/</guid></item><item><title>Home Server Build</title><link>https://captnemo.in/blog/2017/09/17/home-server-build/</link><description>&lt;p&gt;I’d been planning to run my own home server for a while, and this culminated in a mini-ITX build recently. The current build configuration is available at &lt;a href="/setup/homeserver/"&gt;/setup/homeserver/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In no particular order, here were the constraints:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The case should be small (I preferred the Elite 110, but it was unavailable in India).&lt;/li&gt;
  &lt;li&gt;Dual LAN, if possible (decided against it at the end). The plan was to run the entire home network from this directly by plugging in the ISP into the server.&lt;/li&gt;
  &lt;li&gt;Recent i3/i5 for amd64 builds.&lt;/li&gt;
  &lt;li&gt;Enough SATA bays in the cabinet for storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plans for the server:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Scheduled backups from other sources (Android/Laptop)&lt;/li&gt;
  &lt;li&gt;Run Kodi (or perhaps switch to Emby)&lt;/li&gt;
  &lt;li&gt;Run torrents. Transmission-daemon works. Preferably something pluggable and that works with RSS&lt;/li&gt;
  &lt;li&gt;Do amd64 builds. See https://github.com/captn3m0/ideas#arch-linux-package-build-system&lt;/li&gt;
  &lt;li&gt;Host a webserver. This is primarily for serving resources off the internet
    &lt;ul&gt;
      &lt;li&gt;Host some other minor web-services&lt;/li&gt;
      &lt;li&gt;A simple wiki&lt;/li&gt;
      &lt;li&gt;Caldav server&lt;/li&gt;
      &lt;li&gt;Other personal projects&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Sync Server setup. Mainly for the Kindle and the phone.&lt;/li&gt;
  &lt;li&gt;Calibre-server, koreader sync server for the Kindle
    &lt;ul&gt;
      &lt;li&gt;Now looking at libreread as well&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Tiny k8s cluster for running other webapps&lt;/li&gt;
  &lt;li&gt;Run a graylog server for sending other system log data (using papertrail now, has a 200MB limit)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No plans to move mail hosting. That will stay at migadu.com for now.&lt;/p&gt;

&lt;p&gt;I had a lot of spare HDDs that I was going to re-use for this build:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;WD MyBook 3TB (external, shelled).&lt;/li&gt;
  &lt;li&gt;Seagate Expansion: 1TB&lt;/li&gt;
  &lt;li&gt;Seagate Expansion 3TB (external, shelled)&lt;/li&gt;
  &lt;li&gt;Samsung EVO 128GB SSD&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The 2x3TB disks are setup with RAID1 over &lt;code class="language-plaintext highlighter-rouge"&gt;btrsfs&lt;/code&gt;. Important data is snapshotted to the other 1TB disk using btrfs snapshots and subvolumes. In total giving me ~4TB of storage.&lt;/p&gt;

&lt;h2 id="software"&gt;Software&lt;/h2&gt;

&lt;p&gt;Currently running &lt;code class="language-plaintext highlighter-rouge"&gt;kodi-standalone-service&lt;/code&gt; on boot. Have to decide on a easy-to-use container orchestration platform. Choices as of now are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Rancher&lt;/li&gt;
  &lt;li&gt;Docker Swarm&lt;/li&gt;
  &lt;li&gt;Shipyard&lt;/li&gt;
  &lt;li&gt;Terraform&lt;/li&gt;
  &lt;li&gt;Portainer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of these are tuned for multi-host setups, and bring in a lot of complexity as a result. Looking at Portainer, which seems well suited to a single-host setup.&lt;/p&gt;

&lt;p&gt;Other services I’m currently running:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;elibsrv&lt;/code&gt;. Running a patched build with support for ebook-convert&lt;/li&gt;
  &lt;li&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;ubooquity&lt;/code&gt; for online reading of comics&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img alt="" src="/img/home-server.jpg" /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;If you’re interested in my &lt;a href="/setup/homeserver/"&gt;self-hosting setup&lt;/a&gt;, I’m using Terraform + Docker, the code is hosted on &lt;a href="https://git.captnemo.in/nemo/nebula/"&gt;the same server&lt;/a&gt;, and I’ve been writing about my experience and learnings:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="/blog/2017/09/17/home-server-build/"&gt;Part 1, Hardware&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/11/09/home-server-update/"&gt;Part 2, Terraform/Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/18/home-server-learnings/"&gt;Part 3, Learnings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2017/12/31/migrating-from-google/"&gt;Part 4, Migrating from Google (and more)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2018/04/22/home-server-networking/"&gt;Part 5, Home Server Networking&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="/blog/2019/02/24/btrfs-raid-device-replacement-story/"&gt;Part 6, btrfs RAID device replacement&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have any comments, &lt;a href="/contact/"&gt;reach out to me&lt;/a&gt;&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Sun, 17 Sep 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/09/17/home-server-build/</guid></item><item><title>Project Updates</title><link>https://captnemo.in/blog/2017/09/16/project-updates/</link><description>&lt;p&gt;Over the last couple of years, I’ve been involved with lots of side projects, both online and offline. Some of them, I’ve written about on the blog, like my &lt;a href="/blog/2017/05/01/spectrumyzer-visualization/"&gt;music visualizer project&lt;/a&gt;. A few of them, got their own project page, like &lt;a href="/projects/shauryaa/"&gt;the website for my niece&lt;/a&gt; (but no blog post) while some didn’t even get a mention. I thought I’d write about the many-many side projects I’ve started (and abandoned). You might also wanna visit the &lt;a href="/projects/"&gt;/projects&lt;/a&gt; page for the larger projects.&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;&lt;a href="/blog/2017/09/17/home-server-build/"&gt;Home Server Build&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;Sep 2017&lt;/strong&gt; Built a home server, mostly as a HTPC but also as a learning exercise for managing services over Docker.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/sushigo"&gt;Sushi Go&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;Summer 2017&lt;/strong&gt; This is a work-in-progress conversion of Sushi Go (original), the popular card game by Gamewright into Ruby.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/youtube-ripper"&gt;youtube-ripper&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;June 2017&lt;/strong&gt; Downloads music-compilations from YouTube and rips them into multiple tagged MP3 files.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/cosmere-books"&gt;cosmere-books&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;September 2017&lt;/strong&gt; Wrote a EPUB generator for multiple books in the Cosmere. Currently covers 4 different serializations at Tor.com. Also created a project page on all of my ebooks projects at &lt;a href="/ebooks/"&gt;/ebooks/&lt;/a&gt;&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/ideas"&gt;ideas&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;Ongoing&lt;/strong&gt; I maintain a CC0 licensed list of personal ideas. Feel free to use.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="/blog/2017/05/01/spectrumyzer-visualization/"&gt;spectrumyzer&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;May 2017&lt;/strong&gt; Created an animated wallpaper using spectrumyzer. Wrote a &lt;a href="/blog/2017/05/01/spectrumyzer-visualization/"&gt;blog post about it&lt;/a&gt;.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/google-sre-ebook"&gt;google-sre&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;Feb/Sep 2017&lt;/strong&gt; EPUB generator for the Google SRE ebook. Started in February in Python. Gave up and redid it properly in September.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/codechef"&gt;CodeChef Offline&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;March 2012&lt;/strong&gt; I attempted to make a offline repository for CodeChef problems. I spent some time in May 2017 upgrading the project with a cleaner scraper and a Jekyll base.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/hoshruba"&gt;Hoshruba&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;June 2015&lt;/strong&gt; I wrote a script that scraped Tor’s serialized publication of the first book in Hoshruba series to generate EPUB and MOBI files. I would recommend the book if you are interested in reading what many would term the “original fantasy book”&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/hackertray"&gt;HackerTray&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;December 2013 -&lt;/strong&gt; I wrote a Linux PyGTK application that sits in your taskbar using Indicator Applet to show you the latest stories from Hacker News. Looking for a maintainer.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/magicmuggle"&gt;MagicMuggle&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;May 2017&lt;/strong&gt; I wrote a script to convert Magic Muggle (A Harry Potter fanfic about a muggle who accidentally gets into Hogwarts) books from their original reddit posts to EPUB and MOBI files.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://github.com/captn3m0/kerala-it"&gt;Kerala IT Policy&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;March 2017&lt;/strong&gt; Attempted to transcribe the draft IT policies put up by the Government of Kerala. Lots of OCR followed by manual fixes. I stopped working on this when I realized that the government had actually put up a really nice website for this (with clear plaintext, not the bad PDF I was using as the source).&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://lightsaber.captnemo.in"&gt;lightsaber&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;August 2015&lt;/strong&gt; I created a DNS based HTTP-3xx redirect service. Useful if you own a domain and you want it to be redirected, but don’t have a webserver with you. Made as part of the Django Hackathon organized by HackerEarth in Ruby.&lt;/dd&gt;
  &lt;dt&gt;&lt;a href="https://hackercouch.com"&gt;HackerCouch&lt;/a&gt;&lt;/dt&gt;
  &lt;dd&gt;&lt;strong&gt;November 2015&lt;/strong&gt; My hack during hackbeach 2015. Created something best described as “couchsurfing for hackers”. Simple Jekyll/Ruby website hosted on GitHub Pages.&lt;/dd&gt;
&lt;/dl&gt;</description><author>Nemo's Home</author><pubDate>Sat, 16 Sep 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/09/16/project-updates/</guid></item><item><title>Better database migrations in Postgres</title><link>/2017/09/10/better-postgres-migrations/</link><description>&lt;p&gt;As your database grows and scales there are some operations that you need to take more care of than you did when you were just starting. When working with your application in your dev environment you may not be fully aware of the cost of some operations until you run them against production. And at some point most of us have been guilty of it, running some migration that starts at 5 minutes, then 15 minutes in it&amp;rsquo;s still running, and suddenly production traffic is impacted.&lt;/p&gt;
&lt;p&gt;There are two operations that tend to happen quite frequently, each with some straightforward approaches to mitigate having any noticable amount of downtime. Let&amp;rsquo;s look at each of the operations, how they work and then how you can approach them in a safer way.&lt;/p&gt;
&lt;h3 id="adding-new-columns"&gt;
&lt;div&gt;
Adding new columns
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Adding a new column is actually quite cheap in Postgres. When you do this it updates its underlying tracking of the columns that exist–which is almost instant. The part that becomes expensive is when you have some constraint against the column. A constraint could be a primary or foreign key, or some uniqueness constraint. Here Postgres has to scan through all the records in the table to ensure that it&amp;rsquo;s not being violated. Adding some constraint such as &lt;code&gt;not null&lt;/code&gt; does happen some, but is not the most common cause.&lt;/p&gt;
&lt;p&gt;The most common reason for slowness of adding a new column is that most frameworks make it very simple for you to set a default value for the new column. It&amp;rsquo;s one thing to do this for all new records, but when you do this when an existing table it means the database has to read all the records and re-write them with the new default value attached. This isn&amp;rsquo;t so bad for a table with a few hundred records, but for a few hundred million run it then go get yourself coffee, or lunch, or a 5 course meal because you&amp;rsquo;ll be waiting for a while.&lt;/p&gt;
&lt;p&gt;In short, &lt;code&gt;not null&lt;/code&gt; and setting a default value (on creation) of your new column will cause you pain. The solution is to not do those things. But, what if you want to have a default value and don&amp;rsquo;t want to allow &lt;code&gt;nulls&lt;/code&gt;. There&amp;rsquo;s a few simple steps you can take, by essentially splitting your migration up from 1 step to 4 migrations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add your new column &lt;em&gt;that allows nulls&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Start writing your default value on all new records and updates&lt;/li&gt;
&lt;li&gt;Gradually backfill the default value&lt;/li&gt;
&lt;li&gt;Apply your constraint&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Yes, this is a little more work, but it doesn&amp;rsquo;t impact production in nearly the same magnitude.&lt;/p&gt;
&lt;h3 id="indexes"&gt;
&lt;div&gt;
Indexes
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Index creation like most DDL operations holds a lock while it&amp;rsquo;s occurring, this means any new data has to wait for the index to be created and then the new writes flow through. Again when firsting creating the table or on a small table this time is not very noticable. On a large database though, you can again wait minutes to possibly even hours. &lt;em&gt;It&amp;rsquo;s a bit ironic when you think about it that adding an index to speed things up can slow things down while it&amp;rsquo;s happening.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Postgres of course has the answer for this with &lt;code&gt;CONCURRENT&lt;/code&gt; index creation. What this does is gradually build up the index in the background. You can create your index concurrently with: &lt;code&gt;CREATE INDEX CONCURRENTLY&lt;/code&gt;. As soon as the index is created and available as long as you did what you were hoping to Postgres will swap over to using it on queries.&lt;/p&gt;
&lt;h3 id="a-tool-to-help"&gt;
&lt;div&gt;
A tool to help
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s a good practice to understand what is happening when you run a migration and its performance impact. That said you don&amp;rsquo;t have to manage this all on your own. At least for Rails there&amp;rsquo;s a tool to help enforce more of these as you&amp;rsquo;re developing to catch it earlier. &lt;a href="https://github.com/ankane/strong_migrations"&gt;Strong migrations&lt;/a&gt; aims to catch many of these expensive operations for you to have your back, if you&amp;rsquo;re on Rails consider giving it a look.&lt;/p&gt;
&lt;p&gt;Have other tools or tips that can help with database migrations in Postgres? &lt;a href="https://www.twitter.com/craigkerstiens"&gt;Drop me a note&lt;/a&gt; and I&amp;rsquo;ll work to add them to the list.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 10 Sep 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/09/10/better-postgres-migrations/</guid></item><item><title>Working with Rust</title><link>https://boyter.org/2017/09/working-rust/</link><description>&lt;p&gt;For a while I have been wanting to play with a new programming language. Professionally I work with Java, C#, Python and JavaScript and so I went looking for something complimentary to them.&lt;/p&gt;
&lt;p&gt;My first stop was was Go. I started by implementing a vector space search in it which you can see here &lt;a href="https://github.com/boyter/golangvectorspace"&gt;https://github.com/boyter/golangvectorspace&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While I liked the syntax (I still cannot think in Go), the libraries and the performance I realized that Go is close to a hybrid of Java and Python for me. It has the &lt;a href="http://www.boyter.org/2017/03/golang-solution-faster-equivalent-java-solution/"&gt;performance of Java&lt;/a&gt; with the Python style syntax. This is fine but I really wanted to push what I already am familiar with.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Sun, 10 Sep 2017 00:59:08 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/09/working-rust/</guid></item><item><title>Postgres backups: Logical vs. Physical an overview</title><link>/2017/09/03/postgres-backups-physical-vs-logical/</link><description>&lt;p&gt;It&amp;rsquo;s not a very disputed topic that you should backup your database, and further test your backups. What is a little less discussed, at least for Postgres, is the types of backups that exist. Within Postgres there are two forms of backups and understanding them is a useful foundation for anyone working with Postgres. The two backup types are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Physical: which consist of the actual bytes on disk,&lt;/li&gt;
&lt;li&gt;Logical: which is a more portable format.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let&amp;rsquo;s dig into each a bit more so you can better assess which makes sense for you.&lt;/p&gt;
&lt;h3 id="logical-backups"&gt;
&lt;div&gt;
Logical backups
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Logical backups are the most well known type within Postgres. This is what you get when you run &lt;code&gt;pg_dump&lt;/code&gt; against a database. There are a number of different formats you can get from &lt;a href="http://postgresguide.com/utilities/backup-restore.html"&gt;logical backups&lt;/a&gt; and Postgres does a good job of making it easy to compress and configure this backup how you see fit.&lt;/p&gt;
&lt;p&gt;When a logical backup is run against a database it is not throttled, this introduces a noticable load on your database.&lt;/p&gt;
&lt;p&gt;As it&amp;rsquo;s reading the data from disk and generating (in layman terms) a bunch of SQL &lt;code&gt;INSERT&lt;/code&gt; statements, it has to actually see the data. It&amp;rsquo;s of note that older Postgres databases (read: prior to 9.3) there were no checksums against your database. Checksums are just one tool for you to help check against data corruption. Because a logical dump has to actually read and generate the data to insert it will discover any corruption that exists for you.&lt;/p&gt;
&lt;p&gt;This portable format is also very useful to pull down copies from production to different environments. I.e. if you need a copy of production data down on your local laptop &lt;code&gt;pg_dump&lt;/code&gt; is the way to do it. Logical backups are also database specific, but then allow you to dump only certain tables.&lt;/p&gt;
&lt;p&gt;All in all logical backups bring some good features, but come at two cost:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Load on your system&lt;/li&gt;
&lt;li&gt;The backup contains data as of the time when it ran&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="physical-backups"&gt;
&lt;div&gt;
Physical backups
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Physical backups are another option when it comes to backing up your database. As we mentioned earlier it is the physical bytes on disk. To understand physical backups we need to know a bit more under the covers about how Postgres works.&lt;/p&gt;
&lt;p&gt;Postgres, under the covers, is essentially one giant append only log. When you insert data it gets written to the log known as the write-ahead log (commonly called WAL). When you update data a new record gets written to the WAL. When you delete data a new record gets written to the WAL. Nearly all changes in Postgres including to indexes and otherwise cause an update to the WAL.&lt;/p&gt;
&lt;p&gt;With physical backups what you require to be able to create a restore of your database is two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;base backup&lt;/code&gt;, which is a copy of the bytes on disk as of that point and time&lt;/li&gt;
&lt;li&gt;Additional segments of the WAL to put the database in some consistent state.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A physical backup only requires a small amount of WAL to restore the database to some valid state, &lt;em&gt;but&lt;/em&gt; this also gives you some new flexibility. With a base backup plus WAL you can start to replay transactions up to a specific point in time. This is often how point-in-time recovery is performed within Postgres. If you accidentally drop a table, yes&amp;hellip; it happens, you can:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Find a base backup before you dropped the table&lt;/li&gt;
&lt;li&gt;Restore that base backup&lt;/li&gt;
&lt;li&gt;Replay wal segments up to roughly that time just before you dropped the table.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re considering setting up physical backups, consider using a tool like &lt;a href="https://www.citusdata.com/blog/2017/08/18/introducing-wal-g-faster-restores-for-postgres/"&gt;WAL-G&lt;/a&gt; to help.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="logical-vs-physical-which-to-choose"&gt;
&lt;div&gt;
Logical vs. Physical which to choose
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Both are useful and provide different benefits. At smaller scale, say under 100 GB of data logical backups via &lt;code&gt;pg_dump&lt;/code&gt; are something you should absolutely be doing. Because backups happen quickly on smaller databases you may be able to get out without functionality like point-in-time recovery. At larger scale, as you approach 1 TB physical backups start to become your only option. Because of the load introduced by logical backups and the time lapse between capturing them they become less suitable for production.&lt;/p&gt;
&lt;p&gt;Hopefully this primer helps provide a high level overview of the two primary types of backups that exist as options for Postgres. Of course there is much deeper you can go on each, but consider ensuring you have at least one of the two if not both in place. Oh and make sure to test them, an un-tested backup isn&amp;rsquo;t a backup at all.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 03 Sep 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/09/03/postgres-backups-physical-vs-logical/</guid></item><item><title>xmlstarlet, xpath, and confusion</title><link>https://rjp.is/blogging/posts/what-am-i-doing-wrong/</link><description>In which we fail to account for XML namespaces.</description><author>infrequent oscillations</author><pubDate>Mon, 28 Aug 2017 12:06:08 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/what-am-i-doing-wrong/</guid></item><item><title>You Donate $400/Year Thanks To The Best Business Trick Ever</title><link>https://svedic.org/economy/indirect-razors-and-blades-business-model</link><description>I’m going to tell you a story about one ingenious business model that the majority of people are not aware of. It costs average US household around $400 per year. To understand the model, you’ll need to understand three economic &amp;#8230; &lt;a href="https://svedic.org/economy/indirect-razors-and-blades-business-model"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><author>Svedic.org</author><pubDate>Fri, 11 Aug 2017 17:09:16 GMT</pubDate><guid isPermaLink="true">https://svedic.org/economy/indirect-razors-and-blades-business-model</guid></item><item><title>Migration to Ghost v1.0</title><link>https://rjp.is/blogging/posts/migration-to-ghost-v1-0/</link><description>In which we start to get annoyed by Ghost.</description><author>infrequent oscillations</author><pubDate>Tue, 01 Aug 2017 12:38:22 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/migration-to-ghost-v1-0/</guid></item><item><title>Windows "vintage" default desktop colours</title><link>http://blog.pythonaro.com/2017/07/windows-vintage-default-desktop-colours.html</link><description>Note to self: these are the default desktop background colours for old Windows versions.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style="background-color: teal;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt; &lt;b&gt;008080&lt;/b&gt; (RGB 000-128-128) - Windows 95/98&lt;/li&gt;
&lt;li&gt;&lt;span style="background-color: #3a6ea5;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt; &lt;b&gt;3A6EA5&lt;/b&gt; (RGB 058-110-165) - Windows 2000&lt;/li&gt;
&lt;/ul&gt;
(I know you love them, even if setting a wallpaper was the first thing you did after logging on a new PC. It's called nostalgia.)</description><author>Subclassed</author><pubDate>Mon, 31 Jul 2017 22:03:56 GMT</pubDate><guid isPermaLink="true">http://blog.pythonaro.com/2017/07/windows-vintage-default-desktop-colours.html</guid></item><item><title>The Sanity Test</title><link>https://rjp.is/blogging/posts/the-sanity-test/</link><description>In which we are salty about some Perl.</description><author>infrequent oscillations</author><pubDate>Thu, 27 Jul 2017 14:42:26 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/the-sanity-test/</guid></item><item><title>Recent creations</title><link>https://rjp.is/blogging/posts/recent-creations-2017-30-2/</link><description>In which we summarise some craftings.</description><author>infrequent oscillations</author><pubDate>Mon, 24 Jul 2017 18:02:10 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/recent-creations-2017-30-2/</guid></item><item><title>Why I moved from Fitbit to Apple Watch</title><link>https://rjp.is/blogging/posts/why-i-moved-from-fitbit-to-watch-2/</link><description>In which we get annoyed with Fitbit and defect.</description><author>infrequent oscillations</author><pubDate>Mon, 24 Jul 2017 14:02:09 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/why-i-moved-from-fitbit-to-watch-2/</guid></item><item><title>Graphing performance as investigative endeavour</title><link>https://rjp.is/blogging/posts/graphing-performance-as-investigative-endeavour-2/</link><description>In which we see if lap times can tell us about endurance.</description><author>infrequent oscillations</author><pubDate>Fri, 21 Jul 2017 16:32:24 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/graphing-performance-as-investigative-endeavour-2/</guid></item><item><title>Wanted: Collaborative Writer in Berlin</title><link>https://svedic.org/personal/wanted-collaborative-writer-in-berlin</link><description>“The advantage of collaborative writing is that you end up with something for which you will not be personally blamed.&amp;#8221;—Scott Adams This is a unique job, for unique writers. The client is a well-off individual, the owner of a boring &amp;#8230; &lt;a href="https://svedic.org/personal/wanted-collaborative-writer-in-berlin"&gt;Continue reading &lt;span class="meta-nav"&gt;&amp;#8594;&lt;/span&gt;&lt;/a&gt;</description><author>Svedic.org</author><pubDate>Tue, 11 Jul 2017 14:17:13 GMT</pubDate><guid isPermaLink="true">https://svedic.org/personal/wanted-collaborative-writer-in-berlin</guid></item><item><title>awk driven IoT</title><link>https://anisse.astier.eu/awk-driven-iot.html</link><description>&lt;p&gt;With a Raspberry Pi or other modern single-board computers, you can make very simple toys. I started with the hello world of interactive apps: the &lt;a href="https://en.wikipedia.org/wiki/Soundboard_(computer_program)"&gt;soundboard&lt;/a&gt;. But even then, I was too ambitious.&lt;/p&gt;
&lt;h1&gt;The soundpad&lt;/h1&gt;
&lt;p&gt;Since the main target was kids. I wanted a simple, screen-less toy that would teach …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Wed, 05 Jul 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/awk-driven-iot.html</guid></item><item><title>Postgres Open Silicon Valley line-up: First take</title><link>/2017/07/01/postgresopen-sv-line-up/</link><description>&lt;p&gt;This year Postgres open and PGConf SV have combined to great a bigger and better conference right in downtown San Francisco. &lt;em&gt;I&amp;rsquo;m obviously biased as I&amp;rsquo;m one of the co-chairs, and I know every conference organizer says picking the talks was hard, but I&amp;rsquo;m especially excited for the line-up this year&lt;/em&gt;. The hard part for me is going to be which talks do I miss out on because I&amp;rsquo;m sitting in the other session that&amp;rsquo;s ongoing. You can see the full list of &lt;a href="https://postgresql.us/events/sessions/pgopen2017/"&gt;talk and tutorial sessions&lt;/a&gt;, but I thought it&amp;rsquo;d be fun to do a rundown of some of my favorites.&lt;/p&gt;
&lt;h3 id="how-postgres-could-index-itselfhttpspostgresqluseventssessionspgopen2017session399-how-postgres-could-index-itself"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/399-how-postgres-could-index-itself/"&gt;How Postgres could index itself&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/399-how-postgres-could-index-itself/"&gt;Postgres indexing itself&lt;/a&gt; has long been on my wishlist. &lt;a href="https://www.twitter.com/akane"&gt;Andrew Kane&lt;/a&gt; from Instacart, and creator of &lt;a href="https://github.com/ankane/pghero/"&gt;PgHero&lt;/a&gt; has bottled up many learnings into a new tool: &lt;a href="https://medium.com/@ankane/introducing-dexter-the-automatic-indexer-for-postgres-5f8fa8b28f27"&gt;Dexter&lt;/a&gt;. I suspect we&amp;rsquo;ll get a look at all that went into this, how it works, and how you can leverage it to have a more automatically tuned database.&lt;/p&gt;
&lt;h3 id="scaling-a-saas-application-beyond-a-single-postgres-with-citushttpspostgresqluseventssessionspgopen2017session376-scaling-a-saas-application-beyond-a-single-postgres-with-citus"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/376-scaling-a-saas-application-beyond-a-single-postgres-with-citus/"&gt;Scaling a SaaS Application Beyond a Single Postgres with Citus&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Migration talks are all to common, from Postgres to MySQL from MySQL to Postgres, or from &lt;a href="https://containership.engineering/dynamodb-to-postgres-why-and-how-aa891681af4d"&gt;Dynamo to Postgres&lt;/a&gt;. But this one is a little different flavor from Postgres to sharded Postgres with &lt;a href="https://www.citusdata.com"&gt;Citus&lt;/a&gt;. Sharding into a distributed system of course brings new things to consider and think about, and &lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/376-scaling-a-saas-application-beyond-a-single-postgres-with-citus/"&gt;here you&amp;rsquo;ll learn about them&lt;/a&gt; from first hand experience so hopefully you can avoid mistakes yourself.&lt;/p&gt;
&lt;h3 id="concurrency-deep-divehttpspostgresqluseventssessionspgopen2017session374-concurrency-deep-dive"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/374-concurrency-deep-dive/"&gt;Concurrency Deep Dive&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/374-concurrency-deep-dive/"&gt;This one&lt;/a&gt; looks to be a great under the hood look as well as likely very practical. It&amp;rsquo;ll cover MVCC which is really at so much of the core of how Postgres works, but then bring it up to what it means for things like locks. Best of all, this one like so many others comes with lots of real world experience from Segment.&lt;/p&gt;
&lt;h3 id="postgres-window-magichttpspostgresqluseventssessionspgopen2017session364-postgres-window-magic"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/364-postgres-window-magic/"&gt;Postgres window magic&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;h3 id="running-postgresql--instagramhttpspostgresqluseventssessionspgopen2017session371-running-postgresql-instagram"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/371-running-postgresql-instagram/"&gt;Running PostgreSQL @ Instagram&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Instagram is well known as one of the largest apps in the world. They optimized and changed their setup multiple times and probably scaled in about every way possible. &lt;a href="https://postgresql.us/events/sessions/pgopen2017/session/371-running-postgresql-instagram/"&gt;Here we get to learn&lt;/a&gt; about all the various things you need in running at a truly astonishing scale.&lt;/p&gt;
&lt;h3 id="many-many-morehttpspostgresqluseventssessionspgopen2017"&gt;
&lt;div&gt;
&lt;a href="https://postgresql.us/events/sessions/pgopen2017/"&gt;Many many more&lt;/a&gt;
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Of course there&amp;rsquo;s many more. Talks range from looks at new features, to how certain companies are using Postgres. We&amp;rsquo;ve got companies like Instacart and Instagram as mentioned giving talks, to Postgres core committers. Whether you want to learn about the inner workings of Postgres (which often hurts my brain) to how you can simply speed up your app you should find something you like, as long as you like Postgres that is. Take a look at the &lt;a href="https://postgresql.us/events/sessions/pgopen2017/"&gt;full list of sessions&lt;/a&gt; and we hope to see you there.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sat, 01 Jul 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/07/01/postgresopen-sv-line-up/</guid></item><item><title>Before and After</title><link>https://rjp.is/blogging/posts/before-and-after-2/</link><description>In which we tighten up a weave.</description><author>infrequent oscillations</author><pubDate>Wed, 28 Jun 2017 18:33:57 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/before-and-after-2/</guid></item><item><title>Design for searchcode server</title><link>https://boyter.org/2017/06/design-searchcode-server/</link><description>&lt;p&gt;A very brief update about the progress of searchcode server. Currently I am in the middle of reworking how the index is built and maintained. The idea being I want to add zero downtime index rebuilds which requires a blue/green index strategy. It is still very much in flux but the current design is to merge the indexer and searcher which should allow this to happen. I have been playing around with using an iPad as a production device these days and produced the following document.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Tue, 27 Jun 2017 11:18:05 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/06/design-searchcode-server/</guid></item><item><title>Why Refactoring Isn't Popular</title><link>https://cmdev.com/blog/2017-06-22-whynotrefactoring/</link><description>Refactoring is cleaning the kitchen while you cook.</description><author>The Cranky Developer on Crater Moon Development</author><pubDate>Thu, 22 Jun 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://cmdev.com/blog/2017-06-22-whynotrefactoring/</guid></item><item><title>Home Battery Systems – You may de-rate system capacity</title><link>https://boyter.org/2017/06/home-battery-systems-de-rate-system-capacity/</link><description>&lt;p&gt;A quick post. I was looking at the prices to install a home battery system the other day. During the sales process I was informed that for a modular system such as the one provided by Ampetus that if you don&amp;rsquo;t buy 2 or more batteries that&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;you may de rate system capacity&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sound&amp;rsquo;s impressively scary! Slightly worried I asked that it means. Thankfully what it actually means is that instead of getting 3kW delivery using two batteries that one battery matched with the inverter may only deliver 1.5kW. This is not a problem if you are still connected to the grid but it can mean that your inverter isn&amp;rsquo;t working at its full potential. So in short nothing to worry about.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Wed, 14 Jun 2017 11:06:12 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/06/home-battery-systems-de-rate-system-capacity/</guid></item><item><title>Working with time in Postgres</title><link>/2017/06/08/working-with-time-in-postgres/</link><description>&lt;p&gt;A massive amount of reporting queries, whether really intensive data analysis, or just basic insights into your business involving looking at data over a certain time period. Postgres has really rich support for dealing with time out of the box, something that&amp;rsquo;s often very underweighted when dealing with a database. Sure, if you have a time-series database it&amp;rsquo;s implied, but even then how flexible and friendly is it from a query perspective? With Postgres there&amp;rsquo;s a lot of key items available to you, let&amp;rsquo;s dig in at the things that make your life easier when querying.&lt;/p&gt;
&lt;h3 id="date-math"&gt;
&lt;div&gt;
Date math
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;The most common thing I find myself doing is looking at users that have done something within some specific time window. If I&amp;rsquo;m executing this all from my app I can easily inject specific dates, but Postgres makes this really easy for you. Within Postgres you have a type called an interval that is some window of time. And fortunately Postgres takes care of the heavy lifting of how might something translate to or from hours/seconds/milliseconds/etc. Here&amp;rsquo;s just a few examples of things you could do with interals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;lsquo;1 day&amp;rsquo;::interval&lt;/li&gt;
&lt;li&gt;&amp;lsquo;5 days&amp;rsquo;::interval&lt;/li&gt;
&lt;li&gt;&amp;lsquo;1 week&amp;rsquo;::interval&lt;/li&gt;
&lt;li&gt;&amp;lsquo;30 days&amp;rsquo;::interval&lt;/li&gt;
&lt;li&gt;&amp;lsquo;1 month&amp;rsquo;::interval&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;A note that if you&amp;rsquo;re looking to remove something like a full month, you actually want to use 1 month instead of trying to calculate yourself.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With a given interval you can easily shift some window of time, such as finding all users that have signed up for your service within the past week:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #f92672;"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; users
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;WHERE&lt;/span&gt; created_at &lt;span style="color: #f92672;"&gt;&amp;gt;=&lt;/span&gt; now() &lt;span style="color: #f92672;"&gt;-&lt;/span&gt; &lt;span style="color: #e6db74;"&gt;'1 week'&lt;/span&gt;::interval
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="date-functions"&gt;
&lt;div&gt;
Date functions
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Date math makes it pretty easy for you to go and find some specific set of data that applies, but what do you do when you want a broader report around time? There&amp;rsquo;s a few options here. One is to leverage the built-in Postgres functions that help you work with dates and times. &lt;code&gt;date_trunc&lt;/code&gt; is one of the most used ones that will truncate a date down to some interval level. Here you can use the same general values as the above, but simply pass in the type of interval it will be. So if we wanted to find the count of users that signed up per week:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT date_trunc('week', created_at),
count(*)
FROM users
GROUP BY 1
ORDER BY 1 DESC;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This gives us a nice roll-up of how many users signed up each week. What&amp;rsquo;s missing here though is if you have a week that has no users. In that case because no users signed up there is no count of 0, it just simply doesn&amp;rsquo;t exist. If you did want something like this you could generate some range of time and then do a cross join with it against users to see which week they fell into. To do this first you&amp;rsquo;d generate a series of dates:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; generate_series(&lt;span style="color: #e6db74;"&gt;'2017-01-01'&lt;/span&gt;::date, now()::date, &lt;span style="color: #e6db74;"&gt;'1 week'&lt;/span&gt;::interval) weeks
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then we&amp;rsquo;re going to join this against the actual users table and check that the &lt;code&gt;created_at&lt;/code&gt; falls within the right range.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;with weeks as (
select week
from generate_series('2017-01-01'::date, now()::date, '1 week'::interval) week
)
SELECT weeks.week,
count(*)
FROM weeks,
users
WHERE users.created_at &amp;gt; weeks.week
AND users.created_at &amp;lt;= (weeks.week - '1 week'::interval)
GROUP BY 1
ORDER BY 1 DESC;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="timestamp-vs-timestamptz"&gt;
&lt;div&gt;
Timestamp vs. Timestamptz
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;What about storing the times themselves? Postgres has two types of timestamps. It has a generic timestamp and one with timezone embedded in it. In most cases you should generally opt for timestamptz. Why not timestamp? What happens if you move a server, or your server somehow swaps its configuration. Or perhaps more practically what about daylight savings time? In general you might think that you can simply just put in the time as you see it, but when different countries around the world observe things like daylight savings time differently it introduces complexities into your application.&lt;/p&gt;
&lt;p&gt;With timestamptz it&amp;rsquo;ll be aware of the extra parts of your timezone as it comes in. Then when you query from one timezone that accounts for daylights savings you&amp;rsquo;re all covered. There&amp;rsquo;s a &lt;a href="http://phili.pe/posts/timestamps-and-time-zones-in-postgresql/"&gt;number of articles&lt;/a&gt; that cover a bit more in depth on the logic between timestamp and timestamp with timezone, so if you&amp;rsquo;re curious I encourage you to check them out, but by default you mostly just need to use timestamptz.&lt;/p&gt;
&lt;h3 id="more"&gt;
&lt;div&gt;
More
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s a number of other functions and capabilities when it comes to dealing with time in Postrges. You can &lt;code&gt;extract&lt;/code&gt; various parts of a timesetamp or interval such as hour of the day or the month. You can grab the day of the week with &lt;code&gt;dow&lt;/code&gt;. And one of my favorites which is when we celebrate happy hour at Citus, there&amp;rsquo;s a literal for UTC 00:00:00 00:00:00 which is &lt;a href="https://www.postgresql.org/message-id/20050124200645.GA6126%40winnie.fuhr.org"&gt;&lt;code&gt;allballs()&lt;/code&gt;&lt;/a&gt;. If you need to work with dates and times in Postgres I encourage you to check out the &lt;a href="https://www.postgresql.org/docs/current/static/functions-datetime.html"&gt;docs&lt;/a&gt; before you try to re-write something of your own, chances are what you need may already be there.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Thu, 08 Jun 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/06/08/working-with-time-in-postgres/</guid></item><item><title>Write Simple Code to Prevent Headaches Later</title><link>https://benovermyer.com/blog/2017/06/write-simple-code-to-prevent-headaches-later/</link><description>&lt;p&gt;Consider the following code snippet:&lt;/p&gt;
&lt;pre class="giallo" style="color: #F8F8F2; background-color: #282A36;"&gt;&lt;code&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;someVar = false;&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;if ( anotherVar &amp;gt;= 1 ) {&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt; someVar = true;&lt;/span&gt;&lt;/span&gt;
&lt;span class="giallo-l"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, consider this rewrite:&lt;/p&gt;
&lt;pre class="giallo" style="color: #F8F8F2; background-color: #282A36;"&gt;&lt;code&gt;&lt;span class="giallo-l"&gt;&lt;span&gt;someVar = ( anotherVar &amp;gt;= 1 );&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Both snippets work as designed, so why is the second one better? It comes down to simplicity. The first snippet includes an &lt;em&gt;if&lt;/em&gt; block. It would be possible for another programmer to add logic into that block that, while not modifying the final result of &lt;em&gt;someVar&lt;/em&gt;, increases the complexity of the code. This makes it harder to maintain in the long run. The second snippet is very clear about what it does, and is more difficult to tack additional logic onto.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Mon, 05 Jun 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2017/06/write-simple-code-to-prevent-headaches-later/</guid></item><item><title>How to get Ctrl-arrow shortcuts working in RDP sessions on macOS / OSX</title><link>http://blog.pythonaro.com/2017/05/how-to-get-ctrl-arrow-shortcuts-working.html</link><description>&lt;p&gt;It looks like recent versions of the official &lt;a href="https://itunes.apple.com/us/app/microsoft-remote-desktop/id715768417"&gt;Microsoft Remote Desktop client&lt;/a&gt; are a bit shy when it comes to sending CTRL to the remote Windows session. I discovered this because I use Ctrl-Arrow very often to move from word to word, and it just stopped working in RDP.&lt;/p&gt;

&lt;p&gt;The solution is to make sure you don't have any overlapping OSX shortcut - typically, CTRL is used for Mission Control actions. Just disable them from &lt;i&gt;System Preferences -&gt; Keyboard -&gt; Shortcuts -&gt; Mission Control&lt;/i&gt; and you should be good to go. Any recent Apple keyboard will have real keys dedicated to those actions anyway.&lt;/p&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFYZoeouAP5rdL2F3-gZqIJxKtmWDVDbckUNd2LAgWDQJxMRsJryw9y6ZAF2YmZ00VlNP1B6dU3S-yjrd1oQ7R7cUxaoQtp0yn9vMZiUeoXzfj8Rz5VwYpmjuZR29EjDEnNwI6/s1600/Screen+Shot+2017-05-18+at+09.51.48.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFYZoeouAP5rdL2F3-gZqIJxKtmWDVDbckUNd2LAgWDQJxMRsJryw9y6ZAF2YmZ00VlNP1B6dU3S-yjrd1oQ7R7cUxaoQtp0yn9vMZiUeoXzfj8Rz5VwYpmjuZR29EjDEnNwI6/s320/Screen+Shot+2017-05-18+at+09.51.48.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;p&gt;(Come on Microsoft, show some guts - have an option to bypass Mac shortcuts entirely!)&lt;/p&gt;</description><author>Subclassed</author><pubDate>Thu, 18 May 2017 12:01:00 GMT</pubDate><guid isPermaLink="true">http://blog.pythonaro.com/2017/05/how-to-get-ctrl-arrow-shortcuts-working.html</guid></item><item><title>Social Proof and the Bystander Effect</title><link>https://blog.nawaz.org/posts/2017/May/social-proof-and-the-bystander-effect/</link><description>&lt;p&gt;Lately I&amp;#8217;ve been reading the book
&lt;a class="reference external" href="https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X"&gt;Influence&lt;/a&gt;
by Robert Cialdini. The chapter on &lt;em&gt;Social Proof&lt;/em&gt; reminded me of an
&lt;a class="reference external" href="https://www.thisamericanlife.org/radio-archives/episode/420/transcript"&gt;episode&lt;/a&gt;
of &lt;a class="reference external" href="https://www.thisamericanlife.org/"&gt;This American Life&lt;/a&gt; I had
heard some years ago &lt;a class="footnote-reference" href="#footnote-1" id="footnote-reference-1"&gt;[1]&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The episode begins with a mailman delivering mail, when he&amp;nbsp;sees:&lt;/p&gt;
&lt;blockquote&gt;
And they were punching each other and …&lt;/blockquote&gt;</description><author>Beetle Space</author><pubDate>Tue, 16 May 2017 10:00:00 GMT</pubDate><guid isPermaLink="true">https://blog.nawaz.org/posts/2017/May/social-proof-and-the-bystander-effect/</guid></item><item><title>How to identify software licenses using Python, Vector Space Search and Ngram Keywords</title><link>https://boyter.org/2017/05/identify-software-licenses-python-vector-space-search-ngram-keywords/</link><description>&lt;p&gt;&lt;strong&gt;EDIT&lt;/strong&gt; – I have since taken the ideas below improved them and released a command line application you can use to build software license reports &lt;a href="https://github.com/boyter/lc/"&gt;https://github.com/boyter/lc/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The below is mostly a log of my thought process while building out some functionality that I wanted to add into &lt;a href="https://searchcodeserver.com/"&gt;searchcode server&lt;/a&gt;. I kept a record of progress and thoughts while doing this in the hopes that I get some sort of useful blog post out of it. It has been edited somewhat for clarity.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Mon, 08 May 2017 09:54:34 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/05/identify-software-licenses-python-vector-space-search-ngram-keywords/</guid></item><item><title>Building the perfect audio visualization</title><link>https://captnemo.in/blog/2017/05/01/spectrumyzer-visualization/</link><description>&lt;p&gt;I made this as my animated wallpaper recently (Click to play/pause):&lt;/p&gt;

&lt;video class="center-content" poster="/img/spectrum/poster.jpg" src="/videos/spectrum_320.webm" title="Spectrum Visualization Demo." width="320"&gt;&lt;/video&gt;

&lt;p&gt;&lt;em&gt;above video has a audio component, click at your own peril&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What follows is the story and the tech behind making this.&lt;/p&gt;

&lt;h2 id="the-wallpaper"&gt;The Wallpaper&lt;/h2&gt;

&lt;p&gt;I have a long history of using custom wallpapers. This was my wallpaper from 2014-:&lt;/p&gt;

&lt;p&gt;&lt;img alt="Old Wallpaper" src="https://cdn.rawgit.com/captn3m0/avatars/a8255290/wallpaper/1920x1080.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;When I asked &lt;a href="http://vikalpgupta.com/"&gt;Vikalp&lt;/a&gt; to design a new one, I knew I wanted something that
was slightly more softer. This is what he came up with, after a few iterations:&lt;/p&gt;

&lt;p&gt;&lt;img alt="New Wallpaper" src="https://cdn.rawgit.com/captn3m0/avatars/a8255290/wallpaper/minimal.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;This wasn’t the final iteration, and both of us agreed that there was something missing.&lt;/p&gt;

&lt;h2 id="visualizations"&gt;Visualizations&lt;/h2&gt;

&lt;p&gt;I saw a colleague using &lt;a href="https://github.com/karlstav/cava#arch" title="Console-based Audio Visualizer for ALSA (MPD and Pulseaudio)"&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;cava&lt;/code&gt;&lt;/a&gt; and spent a bit of time trying out different
visualization software. The ones that I tried out:&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;&lt;strong&gt;&lt;a href="https://github.com/karlstav/cava#arch" title="Console-based Audio Visualizer for ALSA (MPD and Pulseaudio)"&gt;cava&lt;/a&gt;&lt;/strong&gt;&lt;/dt&gt;
  &lt;dd&gt;works perfectly with i3, runs on a terminal. I couldn’t get it to work cleanly with transparency. &lt;img alt="Cava screenshot using tiling" class="center-content" id="cava:" src="https://rawcdn.githack.com/karlstav/cava/80d465ff2537abf030fa766bda281150c60ac162/example_files/cava.gif" /&gt;&lt;/dd&gt;
  &lt;dt&gt;&lt;strong&gt;&lt;a href="http://projectm.sourceforge.net/" title="MilkDrop was the hardware-accelerated music visualization plugin for Winamp. ProjectM is the port that doesn't need Winamp and works on linux"&gt;mildrop&lt;/a&gt;&lt;/strong&gt;&lt;/dt&gt;
  &lt;dd&gt;Winamp’s legacy. This works great for parties, but is not really an everyday-use visualizer. &lt;img alt="Milkdrop Running using projectM on Linux" class="center-content" id="milkdrop:" src="/img/milkdrop.jpg" /&gt;&lt;/dd&gt;
  &lt;dt&gt;&lt;strong&gt;&lt;a href="https://github.com/HaCk3Dq/spectrumyzer/"&gt;spectrumyzer&lt;/a&gt;&lt;/strong&gt;&lt;/dt&gt;
  &lt;dd&gt;Worked with transparency, but limited to bars visualization.&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;I decided to go ahead with Spectrumyzer (This is the default config):&lt;/p&gt;

&lt;p&gt;&lt;img alt="Default Spectrum Config" class="center-content" src="/img/spectrum/default.jpg" title="Spectrumyzer Default Config" /&gt;&lt;/p&gt;

&lt;h2 id="the-traffic-jam"&gt;The Traffic Jam&lt;/h2&gt;

&lt;p&gt;The very same day, stuck in a traffic jam&lt;sup id="fnref:3"&gt;&lt;a class="footnote" href="#fn:3" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt;, I asked Vikalp for some color ideas on the visualization.&lt;/p&gt;

&lt;p&gt;The obvious 2 were tried first:&lt;/p&gt;

&lt;p&gt;&lt;img alt="Spectrum Dark Blue Config" class="center-content" src="/img/spectrum/darkblue.jpg" title="Spectrumyzer Dark Blue Config" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img alt="Spectrum Yellow Config" class="center-content" src="/img/spectrum/yellow.jpg" title="Spectrumyzer Yellow Config" /&gt;&lt;/p&gt;

&lt;p&gt;It finally dawned on us to use the light blue variant with padding set to zero:&lt;/p&gt;

&lt;p&gt;&lt;img alt="Spectrum Light Blue" class="center-content" src="/img/spectrum/blue.jpg" title="Spectrumyzer Blue Config with zero padding" /&gt;&lt;/p&gt;

&lt;p&gt;Here is one showing the actual positioning (set using the offsets):&lt;/p&gt;

&lt;p&gt;&lt;img alt="Spectrum Offset" class="center-content" src="/img/spectrum/offset.jpg" title="Spectrumyzer offset configuration" /&gt;&lt;/p&gt;

&lt;h2 id="bezier-curves"&gt;Bezier Curves&lt;/h2&gt;

&lt;p&gt;With the padding set to zero, it already looked great. I ended up using this
as my wallpaper for the next one week. Vikalp wanted to make the bars
non-rectangular, and I spent some time figuring out how to make waveforms using
bezier curves&lt;sup id="fnref:1"&gt;&lt;a class="footnote" href="#fn:1" rel="footnote"&gt;2&lt;/a&gt;&lt;/sup&gt;. The basic learning from my experiments were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Cairo has methods for drawing cubic bezier curves.&lt;/li&gt;
  &lt;li&gt;Cubic bezier curves have 2 control points.&lt;/li&gt;
  &lt;li&gt;The control points must be symmetric (equidistant) as well as parallel to the origin points.&lt;/li&gt;
  &lt;li&gt;The parallel part ensures that the ending and starting line segments are always tangential giving a smooth joining.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is roughly what you want to do when drawing waveforms:&lt;/p&gt;

&lt;p&gt;&lt;img alt="Waveform bezier curve" class="center-content" src="/img/bezier.waveform.gif" /&gt;&lt;/p&gt;

&lt;p&gt;If you are interested in playing around with Bezier curves, see &lt;a href="https://www.jasondavies.com/animated-bezier/" title="Animated Bézier Curves, Play with the control points to modify the curves!"&gt;Animated Bézier Curves&lt;/a&gt;. &lt;a href="https://pomax.github.io/bezierinfo/" title="A Primer on Bézier Curves, A free, online book for when you really need to know how to do Bézier things."&gt;A Primer on Bézier Curves&lt;/a&gt; is a math-heavy explanation if you want to read further&lt;sup id="fnref:2"&gt;&lt;a class="footnote" href="#fn:2" rel="footnote"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;The code I wrote picks the midpoints of the bars and then connects them using bezier curves:&lt;/p&gt;

&lt;div class="language-python highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="c1"&gt;# control point cords
# Make sure these are symmetric
&lt;/span&gt;&lt;span class="n"&gt;c1x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect_top_mid_x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="n"&gt;c2x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_rect_top_mid_x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="n"&gt;c1y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rect_top_mid_y&lt;/span&gt;
&lt;span class="n"&gt;c2y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_rect_top_mid_y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I also had to make the number of bars configurable (this is default=64, which doesn’t look great):&lt;/p&gt;

&lt;p&gt;&lt;img alt="Spectrum water 64" class="center-content" src="/img/spectrum/64water.jpg" title="Spectrumyzer curves config doesn't look that great with 64 bars" /&gt;&lt;/p&gt;

&lt;p&gt;Here is the complete final result in HD:&lt;/p&gt;



&lt;h2 id="what-i-learned"&gt;What I learned&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Bezier curves are not magic.&lt;/li&gt;
  &lt;li&gt;Drawing pixels on screen and filling them was quite easy with Cairo and Python.&lt;/li&gt;
  &lt;li&gt;Coding is wizardry. The things that I take for granted every day (take a multi-page website and get useful tabular data out of it, for eg) are unthinkable for most people. The idea of doing water waves was something I knew would be possible before I even looked at the codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’d like to replicate this setup, or build upon it, here is my &lt;a href="https://github.com/captn3m0/dotfiles/blob/master/files/audio/.config/spectrum.conf" title="Just ensure you have the latest spectrumyzer code before using this"&gt;spectrum.conf&lt;/a&gt; file.
I also &lt;a href="https://github.com/HaCk3Dq/spectrumyzer/pull/22" title="Configurable renderers"&gt;filed a PR&lt;/a&gt; (now merged!) to the spectrumyzer project adding support for curve based renders.&lt;/p&gt;

&lt;div class="footnotes"&gt;
  &lt;ol&gt;
    &lt;li id="fn:3"&gt;
      &lt;p&gt;&lt;a href="https://twitter.com/SonyWorldJn"&gt;Sony World Junction&lt;/a&gt; - Where startup ideas are born. &lt;a class="reversefootnote" href="#fnref:3"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:1"&gt;
      &lt;p&gt;The Spectrumyzer codebase turned out to be fairly easy to understand. It was just cairo and pyGTK. &lt;a class="reversefootnote" href="#fnref:1"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
    &lt;li id="fn:2"&gt;
      &lt;p&gt;&lt;a href="https://pomax.github.io/bezierinfo/" title="A Primer on Bézier Curves, A free, online book for when you really need to know how to do Bézier things."&gt;A Primer on Bézier Curves&lt;/a&gt; was published on HN just a few days after I finished this project. &lt;a class="reversefootnote" href="#fnref:2"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description><author>Nemo's Home</author><pubDate>Mon, 01 May 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/05/01/spectrumyzer-visualization/</guid></item><item><title>Why use Postgres (Updated for last 5 years)</title><link>/2017/04/30/why-postgres-five-years-later/</link><description>&lt;p&gt;Five years ago &lt;a href="http://www.craigkerstiens.com/2012/04/30/why-postgres/"&gt;I wrote a post&lt;/a&gt; that got some good attention on why you should use Postgres. Almost a year later I &lt;a href="http://www.craigkerstiens.com/2012/05/07/why-postgres-part-2/"&gt;added a bunch of things&lt;/a&gt; I missed. Many of those items bear repeating, and I&amp;rsquo;ll recap a few of those in the latter half of this post. But in the last 4-5 years there&amp;rsquo;s been a lot of improvements and more reasons added to the list of why you should use Postgres. Here&amp;rsquo;s the rundown of the things that make Postgres a great database you should consider using.&lt;/p&gt;
&lt;h3 id="datatypes-including-jsonb-and-range-types"&gt;
&lt;div&gt;
Datatypes, including JSONB and range types
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Postgres has long had an open and friendly attitude for adding datatypes. It&amp;rsquo;s had arrays, geospatical and more for some time. A few years ago it got two datatypes worth thinking about using:&lt;/p&gt;
&lt;h4 id="jsonb"&gt;
&lt;div&gt;
JSONB
&lt;/div&gt;
&lt;/h4&gt;
&lt;p&gt;JSONB is a binary representation of JSON. It&amp;rsquo;s capable of being indexed on with &lt;code&gt;GIN&lt;/code&gt; and &lt;code&gt;GIST&lt;/code&gt; index types. You can also query into your full JSON document for quick lookups.&lt;/p&gt;
&lt;h4 id="range-types"&gt;
&lt;div&gt;
Range types
&lt;/div&gt;
&lt;/h4&gt;
&lt;p&gt;While it didn&amp;rsquo;t arrive to the same fame as JSONB, &lt;a href="https://wiki.postgresql.org/images/7/73/Range-types-pgopen-2012.pdf"&gt;range types&lt;/a&gt; can be especially handy if they&amp;rsquo;re what you need. Within a single column you can have a range from one value to another–this is especially helpful for time ranges. If you&amp;rsquo;re building a calendaring application or often have a from and to of timestamps then range types can let you put that in a single column. The real benefit is that you can then have constraints that certain time stamps can&amp;rsquo;t overlap or other constraints that may make sense for your application.&lt;/p&gt;
&lt;h3 id="extensions"&gt;
&lt;div&gt;
Extensions
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;d be hard to talk about Postgres without all the ecosystem around it. Extensions are increasingly quite key when it comes to the community and growth of Postgres. Extensions allow you to hook into Postgres very natively without requiring them to be committed back to the core of Postgres. This means they can add rich functionality without being tied to a Postgres release and review cycle. Some great examples of this are:&lt;/p&gt;
&lt;h4 id="citus"&gt;
&lt;div&gt;
Citus
&lt;/div&gt;
&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://www.citusdata.com"&gt;Citus&lt;/a&gt; (who I work for) turns Postgres into a distributed database allowing you to easily shard your database across multiple nodes. To your application it still looks like a single database, but then under the covers it&amp;rsquo;s spread across multiple physical machines and Postgres instances.&lt;/p&gt;
&lt;h4 id="hyperloglog"&gt;
&lt;div&gt;
HyperLogLog
&lt;/div&gt;
&lt;/h4&gt;
&lt;p&gt;This is a personal favorite of mine that allows you to easily have close-enough distinct counts pre-aggregated, but then also do various operations on them across days such as unions, intersections, and more. &lt;a href="https://www.citusdata.com/blog/2017/04/04/distributed_count_distinct_with_postgresql/"&gt;HyperLogLog and other sketch algorithms&lt;/a&gt; can be extremely common across large datasets and distributed systems, but it&amp;rsquo;s especially exciting to find them pretty close to out of the box in Postgres.&lt;/p&gt;
&lt;h4 id="postgis"&gt;
&lt;div&gt;
PostGIS
&lt;/div&gt;
&lt;/h4&gt;
&lt;p&gt;PostGIS isn&amp;rsquo;t new, but it&amp;rsquo;s worth highlighting again. It&amp;rsquo;s commonly regarded as the most advanced geospatial database. PostGIS adds new advanced geospatial datatypes, operators, and makes it easy to do many of the location based activities you need if you&amp;rsquo;re dealing with mapping or routing.&lt;/p&gt;
&lt;h3 id="logical-replication"&gt;
&lt;div&gt;
Logical replication
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;For many years the biggest knock against Postgres was the difficulty in setting up replication. Originally this was any form of replication, but then streaming replication came along (this is streaming of the binary WAL or write-ahead-log format). Tools like &lt;a href="https://github.com/wal-e/wal-e"&gt;wal-e&lt;/a&gt; help leverage much of the Postgres mechanisms for things like disaster recovery.&lt;/p&gt;
&lt;p&gt;Then we had the foundation for logical replication in recent releases, though it still required an &lt;a href="https://github.com/2ndQuadrant/pglogical"&gt;extension&lt;/a&gt; to Postgres so it wasn&amp;rsquo;t 100% out of the box. And, then finally we got full logical replication. Logical replication allows the sending of more or less actual commands, this means you could replicate only certain commands or certain tables.&lt;/p&gt;
&lt;h3 id="scale"&gt;
&lt;div&gt;
Scale
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;In addition to all of the usability featuers we&amp;rsquo;ve seen Postgres continue to get better and better at &lt;a href="https://www.slideshare.net/fuzzycz/postgresql-performance-improvements-in-95-and-96"&gt;performance&lt;/a&gt;. In particular we now have the foundations for &lt;a href="https://www.postgresql.org/docs/current/static/parallel-query.html"&gt;parallelism&lt;/a&gt; and on some queries you&amp;rsquo;ll see much better performance. Then if you need even greater scale than single node Postgres (such as 122 or 244 GB of RAM on RDS or Heroku) you have options like &lt;a href="https://www.citusdata.com"&gt;Citus&lt;/a&gt; which was mentioned earlier that can help you scale out.&lt;/p&gt;
&lt;h3 id="richer-indexing"&gt;
&lt;div&gt;
Richer indexing
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Postgres already had some pretty powerful indexing before with &lt;a href="https://www.postgresql.org/docs/9.5/static/textsearch-indexes.html"&gt;GIN and GiST&lt;/a&gt;, those are now useful for JSONB. But we&amp;rsquo;ve also seen the arrival of KNN indexes and Sp-GiST and have even more on the way.&lt;/p&gt;
&lt;h3 id="upsert"&gt;
&lt;div&gt;
Upsert
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Upsert was a work in progress for several years. It was one of those features that most people hacked around with &lt;a href="http://www.craigkerstiens.com/2013/11/18/best-postgres-feature-youre-not-using/"&gt;CTEs&lt;/a&gt;, but that could create race conditions. It was also one of the few features MySQL had over Postgres. And just over a year ago we got &lt;a href="http://www.craigkerstiens.com/2015/05/08/upsert-lands-in-postgres-9.5/"&gt;official upsert&lt;/a&gt; support.&lt;/p&gt;
&lt;h3 id="foreign-data-wrappers"&gt;
&lt;div&gt;
Foreign Data Wrappers
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Okay, yes foreign data wrappers did exist many years ago. If you&amp;rsquo;re not familiar with foreign data wrappers, they allow you map an external data system to tables directly in Postgres. This means could could for example interact and query your &lt;a href="http://www.craigkerstiens.com/2012/10/18/connecting_to_redis_from_postgres/"&gt;Redis&lt;/a&gt; database from directly in Postgres with SQL. They&amp;rsquo;ve continued to be improved more and more from what we had over 5 years ago. In particular we got support for write-able foreign data wrappers, meaning you can write data to other systems from directly in Postgres. There&amp;rsquo;s also now an official Postgres FDW which comes out of the box with Postgres and it by itself is quite useful when querying across various Postgres instances.&lt;/p&gt;
&lt;h3 id="much-more"&gt;
&lt;div&gt;
Much more
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;And if you missed the &lt;a href="http://www.craigkerstiens.com/2012/04/30/why-postgres/"&gt;earlier editions&lt;/a&gt; of this, please feel free to &lt;a href="http://www.craigkerstiens.com/2012/05/07/why-postgres-part-2/"&gt;check them out&lt;/a&gt;. The cliff notes of them include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Window functions&lt;/li&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Custom languages (PLV8 anyone?)&lt;/li&gt;
&lt;li&gt;NoSQL datatypes&lt;/li&gt;
&lt;li&gt;Custom functions&lt;/li&gt;
&lt;li&gt;Common table expressions&lt;/li&gt;
&lt;li&gt;Concurrent index creation&lt;/li&gt;
&lt;li&gt;Transactional DDL&lt;/li&gt;
&lt;li&gt;Foreign Data Wrappers&lt;/li&gt;
&lt;li&gt;Conditional and functional indexes&lt;/li&gt;
&lt;li&gt;Listen/Notify&lt;/li&gt;
&lt;li&gt;Table inheritance&lt;/li&gt;
&lt;li&gt;Per transaction synchronous replication&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re looking for a deeper resource on Postgres I recommend the book &lt;a href="https://theartofpostgresql.com/?affiliate=cek"&gt;The Art of PostgreSQL&lt;/a&gt;. It is by a personal friend that has aimed to create the definitive guide to Postgres, from a developer perspective. If you use code CRAIG15 you&amp;rsquo;ll receive 15% off as well.&lt;/em&gt;&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 30 Apr 2017 23:55:56 GMT</pubDate><guid isPermaLink="true">/2017/04/30/why-postgres-five-years-later/</guid></item><item><title>Deconstructing an image</title><link>https://rjp.is/blogging/posts/deconstructing-an-image-2/</link><description>The iOS apps and processing steps used to make something moderately interesting from photos of a kitten and a spider.</description><author>infrequent oscillations</author><pubDate>Sun, 23 Apr 2017 17:29:41 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/deconstructing-an-image-2/</guid></item><item><title>Ignorance</title><link>https://blog.nawaz.org/posts/2017/Apr/ignorance/</link><description>&lt;p&gt;There are two types of people: Those who are uncomfortable with their
own ignorance, and those who aim to&amp;nbsp;understand.&lt;/p&gt;
&lt;p&gt;The former will be quick to fill the void with an explanation. The
latter will not stop there, but will seek to test the&amp;nbsp;explanation.&lt;/p&gt;
&lt;p&gt;Most people are of the …&lt;/p&gt;</description><author>Beetle Space</author><pubDate>Sun, 23 Apr 2017 10:00:00 GMT</pubDate><guid isPermaLink="true">https://blog.nawaz.org/posts/2017/Apr/ignorance/</guid></item><item><title>Reciprocity and the Golden Rule</title><link>https://blog.nawaz.org/posts/2017/Apr/reciprocity-and-the-golden-rule/</link><description>&lt;p&gt;Lately I&amp;#8217;ve been reading the book
&lt;a class="reference external" href="https://www.amazon.com/Influence-Psychology-Persuasion-Robert-Cialdini/dp/006124189X"&gt;Influence&lt;/a&gt;
by Robert Cialdini. In it he talks about the &lt;em&gt;principle of reciprocity&lt;/em&gt;.
We tend to repay, in kind, what someone else has given us - even when we
did not want it, and even when we did not &lt;em&gt;take&lt;/em&gt;&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;If someone gives …&lt;/p&gt;</description><author>Beetle Space</author><pubDate>Sat, 22 Apr 2017 10:00:00 GMT</pubDate><guid isPermaLink="true">https://blog.nawaz.org/posts/2017/Apr/reciprocity-and-the-golden-rule/</guid></item><item><title>Book Review (2016)</title><link>https://captnemo.in/blog/2017/04/02/book-review-2016/</link><description>&lt;p&gt;I tweeted this a while back about my reading progress in 2016, and thought I’d do a post about what I read.&lt;/p&gt;

&lt;blockquote class="twitter-tweet"&gt;&lt;p dir="ltr" lang="en"&gt;Made a graph of my &lt;a href="https://twitter.com/goodreads"&gt;@goodreads&lt;/a&gt; reading progress in 2016. I only picked up the pace sometime in May, but managed to read ~10k pages this year.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://pbs.twimg.com/media/C2D9p9DXEAADajk.png" /&gt;&lt;/p&gt;
&amp;mdash; Nemo (@captn3m0) &lt;a href="https://twitter.com/captn3m0/status/819934060256563201"&gt;January 13, 2017&lt;/a&gt;&lt;/blockquote&gt;

&lt;p&gt;Continuing with the &lt;a href="/blog/2016/02/15/2015-in-review/"&gt;review tradition from last year&lt;/a&gt;, here are the top 3 books that I read in 2016:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/26892110-the-library-at-mount-char"&gt;The Library at Mount Char&lt;/a&gt; [&lt;a href="https://www.goodreads.com/review/show/1648561385?book_show_action=false&amp;amp;from_review_page=1"&gt;review&lt;/a&gt;]&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/25667918-binti"&gt;Binti&lt;/a&gt; (Hugo winner for Best Novella, SF)&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/7604.Lolita"&gt;Lolita&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other books that I enjoyed were “Bands of Mourning”, the 3rd book in Mistborn Era 2, and the Powder Mage Trilogy which I found hard to put down.&lt;/p&gt;

&lt;p&gt;I decided to aim for 36 books in 2016 (as well as 2017 now), and crossed that nicely. I picked 36 because it corresponds to 3 books a month or 1 book every 10 days, which makes for a goal that is easily tracked. I count everything that goodreads might count as a book (which is both good and bad), but I stick to it. Far more important for me would be the page count, which I charted at the end of the year and I read ~830 pages a month, which I’m pretty happy with.&lt;/p&gt;

&lt;p&gt;I’m hoping to read more technical books in 2017, and have made some progress on that front with re-reading &lt;a href="https://sarabander.github.io/sicp/"&gt;SICP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are interested in the script that generated the graph, you can find it on &lt;a href="https://github.com/captn3m0/what-to-read/blob/master/stats.rb"&gt;github&lt;/a&gt;.&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Sun, 02 Apr 2017 03:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/04/02/book-review-2016/</guid></item><item><title>Why is this GoLang solution faster than the equivalent Java Solution?</title><link>https://boyter.org/2017/03/golang-solution-faster-equivalent-java-solution/</link><description>&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;At work there is a tradition of a Friday quiz being posted by the winner of the previous week. I missed out on the most recent one due to having to duck off early to do my tax but the problem was rather an interesting one.&lt;/p&gt;
&lt;p&gt;The challange itself is not as simple as you would initally think and taken from a 2015 IBM Ponder This &lt;a href="https://www.research.ibm.com/haifa/ponderthis/challenges/May2015.html"&gt;https://www.research.ibm.com/haifa/ponderthis/challenges/May2015.html&lt;/a&gt;&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Fri, 31 Mar 2017 01:52:01 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/03/golang-solution-faster-equivalent-java-solution/</guid></item><item><title>Vulnerability Report: ACT Corp</title><link>https://captnemo.in/blog/2017/03/26/act-vulnerability/</link><description>&lt;p&gt;ACT, for those who don’t know is one of India’s most popular broadband providers.&lt;/p&gt;

&lt;p&gt;This is a very brief and concise summary.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ACT has a mobile application&lt;/li&gt;
  &lt;li&gt;That allows you to login and check your plan details, data usage etc&lt;/li&gt;
  &lt;li&gt;I’ve been wanting to build a command line application that lets me check the balance easily&lt;/li&gt;
  &lt;li&gt;I tried scripting their website, but it was too much javascript.&lt;/li&gt;
  &lt;li&gt;The mobile app uses an API to do the same&lt;/li&gt;
  &lt;li&gt;The API happens to have really bad auth&lt;/li&gt;
  &lt;li&gt;Got fixed almost 3 months after reporting this.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Request&lt;/strong&gt;&lt;/p&gt;

&lt;div class="language-sh highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;curl https://myfibernet.actcorp.in/api/user/plandetails &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authtoken: 2aee21dfb1ef77707c30f48ccc513ad60b74d1fc6a84d60ecc32323ab5941469"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Apiversion: 1.0"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Appversion: 32"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Devicetype: 1"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Deviceid: 68590327e3e0ca81"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Mobilenumber: 9999999999"&lt;/span&gt; &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Mid: 8973808103928d98703e65c0106b7a9d4001886234afbc2d7ce6415b75f9c216"&lt;/span&gt; &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{"username":"11111111"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The API responds back with the following:&lt;/p&gt;

&lt;div class="language-json highlighter-rouge"&gt;&lt;div class="highlight"&gt;&lt;pre class="highlight"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plan_details"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"agreement_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"agreement_no"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"XXXXXXXXXX"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"promotion_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"package_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ACTESS01M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"package_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"agreement_startdate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DD/MM/YYYY"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"expiry_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"entity_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"subscription_period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"payterm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"billingcycle_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"[]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"contract_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"outlets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"service_points"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"package_tenure"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"due_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"product_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"product_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"product_desc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plan_usage_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ACTESS01M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ACTESS01M"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"outbyteslimit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;322122547200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"outbytesremaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;153400581140&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"outbytesused"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;168721966060&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bill_info"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"accountno"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"111111112233"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"subscribername"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NAME"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"phonenumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PHONENUMBER"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"address"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"line1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YUP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"line2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"THESE TWO LINES WERE FILLED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"line3"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"district"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AND THIS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"city"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BANGALORE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KARNATAKA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"country"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"India"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"billno"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10000001111"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"billdate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DD/MM/2016"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"account_period"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"01/MM/2016-30/MM/2016"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"previous_due"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"current_invoice_amt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total_due"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"bill_due_date"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"15 Nov 2016"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Some of these are empty fields, and some values that I didn’t understand I’ve replaced with &lt;code class="language-plaintext highlighter-rouge"&gt;[]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The fun part is that the request is actually a POST and contains the following data:&lt;/p&gt;

&lt;p&gt;&lt;code class="language-plaintext highlighter-rouge"&gt;{"username":"11111111"}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I happen to have friends who also use ACT. I &lt;a href="https://twitter.com/captn3m0/status/803579876502405120"&gt;asked around for usernames&lt;/a&gt;, and just by changing this one parameter in the request, I could access the complete details of almost everyone else.&lt;/p&gt;

&lt;p&gt;Almost everyone, because for certain cases, I get a valid empty response. Valid because it has the same schema, but empty because all values are empty strings. Don’t know what that happens consistently only for certain accounts. (One of these was a Hyd account, the other in BLR).&lt;/p&gt;

&lt;p&gt;If you are interested I’m working on a simple API that lets you access the ACT API to check the same details. It would ask you for an OTP the first time you login, and then cache the credentials to let you check the balance easily.&lt;/p&gt;

&lt;p&gt;&lt;del&gt;I’ve reported this to ACT as soon as I found it. Will disclose after I’ve given them some time!&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: This was reported and fixed by ACT after I managed to find a contact via an investor (really!).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeline&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Date&lt;/th&gt;
      &lt;th&gt;Details&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;29 Nov 2016&lt;/td&gt;
      &lt;td&gt;Vulnerability Identified&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;29 Nov 2016&lt;/td&gt;
      &lt;td&gt;Email sent to ACT, no response&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6 Dec 2016&lt;/td&gt;
      &lt;td&gt;Email sent with partial customer details to explain scope of the issue, no response&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;8 Dec 2016&lt;/td&gt;
      &lt;td&gt;Reminder sent, no response&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20 Jan 2017&lt;/td&gt;
      &lt;td&gt;Another reminder with a writeup sent. I also set a deadline of 29th January (2 months since first contact). Also got in touch with CERT-IN. &lt;em&gt;No response&lt;/em&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;23 Jan 2017&lt;/td&gt;
      &lt;td&gt;Accidentally an investor in ACT saw my tweet and responded over twitter. Send a writeup, along with the suggestion to take down the application&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;24 Jan 2017&lt;/td&gt;
      &lt;td&gt;ACT reports issue is fixed. I test and report back as fixed the next day&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;26 Mar 2017&lt;/td&gt;
      &lt;td&gt;Report published&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;However, the huge timeline involved here pretty much guarantees that if you are an ACT customer,
your data is out there in the public.&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Sun, 26 Mar 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/03/26/act-vulnerability/</guid></item><item><title>CCTC Challenge VM</title><link>https://captnemo.in/blog/2017/03/25/cctc-vm-images/</link><description>&lt;p&gt;This is specifically about the contest held in 2011,
6 years ago. I’ve written about my experience
during the contest &lt;a href="/blog/2011/11/20/cctc-blog/"&gt;on this blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More specifically, Round 2 of the contest was a pentesting
scenario where we were only provided with a VM image
and asked to test it and report any vulnerabilities
that we found.&lt;/p&gt;

&lt;p&gt;I recently found the VirtualBox images, and thought
I’d share them as a easy intro to web security.&lt;/p&gt;

&lt;h1 id="instructions"&gt;Instructions&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="/contact/"&gt;Reach out to me&lt;/a&gt; for the VM image&lt;/li&gt;
  &lt;li&gt;Hack.&lt;/li&gt;
  &lt;li&gt;Credentials are student:student (username:password)&lt;/li&gt;
  &lt;li&gt;Open /cctc in your browser.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id="rules"&gt;Rules&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;Only application and its serving components can be tested for vulnerabilities. The serving components include
    &lt;ul&gt;
      &lt;li&gt;Webserver&lt;/li&gt;
      &lt;li&gt;Operating System&lt;/li&gt;
      &lt;li&gt;Any other services/files in the guest machine and guest operating system&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Any vulnerability identified in any component outside the above mentioned ones, will not be used for evaluation&lt;/li&gt;
  &lt;li&gt;All participants should necessarily submit all the exploit codes/custom scripts written to identify the vulnerabilities in the system.&lt;/li&gt;
  &lt;li&gt;The deadline for the original challenge was 2 weeks, but you’re free to take as much time as you want. Feel free to publish a list of vulnerabilities you find.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://docs.google.com/spreadsheets/d/1s_o-HGlS2dKbDnm2mjTbgXpDHDHQgMYXlbOMEVNaBvY/edit?usp=sharing"&gt;The attached spreadsheet&lt;/a&gt; provides format of the report, challenges in scope, and the details to be filled out for each vulnerability identified.&lt;/p&gt;

&lt;p&gt;The tasks to be performed are mentioned in the report. Each task consists of the following sections:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Vulnerability/Vulnerabilities - You need to write the description of the vulnerability&lt;/li&gt;
  &lt;li&gt;Root Cause(s) - What is the root cause of the vulnerability?&lt;/li&gt;
  &lt;li&gt;Approach adopted (Steps with screenshots) – Write the steps followed to exploit the vulnerability along with screenshot of the final screen and/or intermediate steps.&lt;/li&gt;
  &lt;li&gt;Remediation with sample code snippet – Write the remediation steps to address this vulnerability. Also, write the sample code if applicable.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Also &lt;a href="https://drive.google.com/file/d/0B2qzfUR1eWklMHJONkZPUkVqLWZPS3pwTzFDYW84aVJhbjZB/view?usp=sharing"&gt;attached is a step by step installation guide&lt;/a&gt; for application set-up.&lt;/p&gt;

&lt;p&gt;Few points to be considered:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Challenges can be attempted and completed in any order.&lt;/li&gt;
  &lt;li&gt;Only the application and its serving components can be tested for vulnerabilities. All other components like VMware, if tested for security issues, would lead to disqualification.&lt;/li&gt;
  &lt;li&gt;I will not be responsible for the discovery/notification of any zero day vulnerability in any software.  If any zero-day vulnerability is identified, it is the responsibility of the concerned participant to notify the vulnerability to the respective vendor as per vendor’s policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are really interested, you can find a copy of the report
we submitted at &lt;a href="/reports/cctc/"&gt;/reports/cctc&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to Harshil and Shobhit for working alongside on this.&lt;/p&gt;</description><author>Nemo's Home</author><pubDate>Sat, 25 Mar 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://captnemo.in/blog/2017/03/25/cctc-vm-images/</guid></item><item><title>Getting started with JSONB in Postgres</title><link>/2017/03/12/getting-started-with-jsonb-in-postgres/</link><description>&lt;p&gt;JSONB is an awesome datatype in Postgres. I find myself using it on a weekly basis these days. Often in using some API (such as &lt;a href="https://www.clearbit.com"&gt;clearbit&lt;/a&gt;) I&amp;rsquo;ll get a JSON response back, instead of parsing that out into a table structure it&amp;rsquo;s really easy to throw it into a JSONB then query for various parts of it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re not familiar with JSONB, it&amp;rsquo;s a binary representation of JSON in your database. You can read a bit more about it vs. JSON &lt;a href="https://www.citusdata.com/blog/2016/07/14/choosing-nosql-hstore-json-jsonb/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In working with JSONB here&amp;rsquo;s a few quick tips to get up and running with it even faster:&lt;/p&gt;
&lt;h3 id="indexing"&gt;
&lt;div&gt;
Indexing
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;For the most part you don&amp;rsquo;t have to think to much about this. With Postgres powerful indexing types you can add one index and have everything within the JSON document, all the keys and all the values, automatically indexed. The key here is to add a &lt;code&gt;GIN&lt;/code&gt; index. Once this is done queries should be much faster where you&amp;rsquo;re searching for some value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;CREATE&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;INDEX&lt;/span&gt; idx_data &lt;span style="color: #66d9ef;"&gt;ON&lt;/span&gt; companies &lt;span style="color: #66d9ef;"&gt;USING&lt;/span&gt; GIN (&lt;span style="color: #66d9ef;"&gt;data&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="querying"&gt;
&lt;div&gt;
Querying
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Querying is a little bit more work, but once you get the basics it can be pretty straight forward. There&amp;rsquo;s a few new operators you&amp;rsquo;ll want to quickly ramp up on and from there querying becomes easy.&lt;/p&gt;
&lt;p&gt;For the most basic part you now have an operator so traverse down the various keys. First let&amp;rsquo;s get some idea of what the JSON looks like so we can have something to work with. Here&amp;rsquo;s a sample set of data that we get back from Clearbit:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;{
"domain": "citusdata.com",
"company": {
"id": "b1ff2bdf-0d8d-4d6d-8bcc-313f6d45996a",
"url": "http:\/\/citusdata.com",
"logo": "https:\/\/logo.clearbit.com\/citusdata.com",
"name": "Citus Data",
"site": {
"h1": null,
"url": "http:\/\/citusdata.com",
"title": "Citus Data",
},
"tags": [
"SAAS",
"Enterprise",
"B2B",
"Information Technology &amp;amp; Services",
"Technology",
"Software"
],
"domain": "citusdata.com",
"twitter": {
"id": "304455171",
"bio": "Builders of Citus, the extremely scalable PostgreSQL database.",
"site": "https:\/\/t.co\/hKpZjIy7Ej",
"avatar": "https:\/\/pbs.twimg.com\/profile_images\/630900468995108865\/GJFCCXrv_normal.png",
"handle": "citusdata",
"location": "San Francisco, CA",
"followers": 3770,
"following": 570
},
"category": {
"sector": "Information Technology",
"industry": "Internet Software &amp;amp; Services",
"subIndustry": "Internet Software &amp;amp; Services",
"industryGroup": "Software &amp;amp; Services"
},
"emailProvider": false
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sorry it&amp;rsquo;s a bit long, but it gives us a good example to work with.&lt;/p&gt;
&lt;h3 id="basic-lookups"&gt;
&lt;div&gt;
Basic lookups
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Now let&amp;rsquo;s query something fairly basic, the domain:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #f92672;"&gt;#&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;data&lt;/span&gt;&lt;span style="color: #f92672;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'domain'&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; companies
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;WHERE&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;domain&lt;/span&gt;&lt;span style="color: #f92672;"&gt;=&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'citusdata.com'&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;LIMIT&lt;/span&gt; &lt;span style="color: #ae81ff;"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #f92672;"&gt;?&lt;/span&gt;&lt;span style="color: #66d9ef;"&gt;column&lt;/span&gt;&lt;span style="color: #f92672;"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;-----------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;&lt;/span&gt; &lt;span style="color: #e6db74;"&gt;"citusdata.com"&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;-&amp;gt;&lt;/code&gt; is likely the first operator you&amp;rsquo;ll use in JSONB. It&amp;rsquo;s helpful to traverse the JSON. Though of you&amp;rsquo;re looking to get the value as text you&amp;rsquo;ll actually want to use &lt;code&gt;-&amp;gt;&amp;gt;&lt;/code&gt;. Instead of giving you some quoted response back or JSON object you&amp;rsquo;re going to get it as text which will be a bit cleaner:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #f92672;"&gt;#&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;data&lt;/span&gt;&lt;span style="color: #f92672;"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'domain'&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; companies
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;WHERE&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;domain&lt;/span&gt;&lt;span style="color: #f92672;"&gt;=&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'citusdata.com'&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;LIMIT&lt;/span&gt; &lt;span style="color: #ae81ff;"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #f92672;"&gt;?&lt;/span&gt;&lt;span style="color: #66d9ef;"&gt;column&lt;/span&gt;&lt;span style="color: #f92672;"&gt;?&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;-----------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;&lt;/span&gt; citusdata.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="filtering-for-values"&gt;
&lt;div&gt;
Filtering for values
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Now with something like clearbit you may want to filter out for only certain type of companies. We can see in the example data that there&amp;rsquo;s a bunch of tags. If we wanted to find only companies that had the tag B2B we could use the &lt;code&gt;?&lt;/code&gt; operator once we&amp;rsquo;ve targetted down to that part of the JSON. The &lt;code&gt;?&lt;/code&gt; operator will tell us if some part of JSON has a top level key:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; &lt;span style="color: #f92672;"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; companies
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;WHERE&lt;/span&gt; &lt;span style="color: #66d9ef;"&gt;data&lt;/span&gt;&lt;span style="color: #f92672;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'company'&lt;/span&gt;&lt;span style="color: #f92672;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #e6db74;"&gt;'tags'&lt;/span&gt; &lt;span style="color: #f92672;"&gt;?&lt;/span&gt; &lt;span style="color: #e6db74;"&gt;'B2B'&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jsonb-but-pretty"&gt;
&lt;div&gt;
JSONB but pretty
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;In querying JSONB you&amp;rsquo;ll typically get a nice compressed set of JSON back. While this is all fine if you&amp;rsquo;re putting it into your application, if you&amp;rsquo;re manually debugging and testing things you probably want something a bit more readable. Of course Postgres has your back here and you can wrap your JSONB with a pretty print function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; jsonb_pretty(&lt;span style="color: #66d9ef;"&gt;data&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; companies;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="much-more"&gt;
&lt;div&gt;
Much more
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;There&amp;rsquo;s a lot more in the &lt;a href="https://www.postgresql.org/docs/9.5/static/functions-json.html"&gt;docs&lt;/a&gt; that you can find handy for the specialized cases when you need them. &lt;code&gt;jsonb_each&lt;/code&gt; will expand a JSONB document into individual rows. So if you wanted to count the number of occurences of every tag for a company, this would help. Want to parse out a JSONB to a row/record in Postgres there&amp;rsquo;s &lt;code&gt;jsonb_to_record&lt;/code&gt;. The docs are your friends for about everything you want to do but hopefully these few steps help kick start things if you want to get started with &lt;code&gt;JSONB&lt;/code&gt;.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 12 Mar 2017 22:55:56 GMT</pubDate><guid isPermaLink="true">/2017/03/12/getting-started-with-jsonb-in-postgres/</guid></item><item><title>Deploying FreeBSD on Linode unattended in minutes</title><link>http://notes.eatonphil.com/deploying-freebsd-on-linode-unattended-in-minutes.html</link><description>&lt;p&gt;I became a FreeBSD user over 2 years ago when I wanted to see what all
the fuss was about. I swapped my y410p dual-booting Windows / Ubuntu
with FreeBSD running Gnome 3. I learned a lot during the transition
and came to appreciate FreeBSD as a user. I soon began running FreeBSD
as my OS of choice on cloud servers I managed. So naturally, when I
started working at Linode a year ago I wanted to run FreeBSD servers
on Linode too.&lt;/p&gt;
&lt;p&gt;Linode is a great platform for running random unofficial images
because you have much control over the configuration. I followed
&lt;a href="https://www.linode.com/docs/tools-reference/custom-kernels-distros/install-freebsd-on-linode/"&gt;existing&lt;/a&gt; &lt;a href="https://forum.linode.com/viewtopic.php?f=20&amp;amp;t=12080"&gt;guides&lt;/a&gt; closely and was soon able to get a number of
operating systems running on Linodes by installing them manually:
FreeBSD, OpenBSD, NetBSD, Minix3, and SmartOS to date.&lt;/p&gt;
&lt;p&gt;Unofficial images come at a cost though. In particular, I became
frustrated having to reinstall using the installer every time I
managed to trash the disk. So over the past year, I spent time trying
to understand the automated installation processes across different
operating systems and Linux distributions.&lt;/p&gt;
&lt;p&gt;Unattended installations are tough. The methods for doing them differ
wildly. On RedHat, Fedora, and CentOS there is &lt;a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/installation_guide/ch-kickstart2"&gt;Kickstart&lt;/a&gt;. On
Debian and Ubuntu there is &lt;a href="https://wiki.debian.org/DebianInstaller/Preseed"&gt;preseeding&lt;/a&gt;. Gentoo, Arch, and FreeBSD
don't particularly have a framework for unattended installs, but the
entire installation process is well-documented and inherently
scriptable (if you put in the effort). OpenBSD has
&lt;a href="http://man.openbsd.org/OpenBSD-6.0/man8/autoinstall.8"&gt;autoinstall&lt;/a&gt;. Trying to understand each and every one of these
potential installation methods was pretty defeating for getting
started on a side-project.&lt;/p&gt;
&lt;p&gt;A few weeks ago, I finally had the silly revelation that I didn't need
to script the installation process -- at least initially. I only had
to have working images available somewhere that could be copied to new
Linodes. Some OSs / distributions may provide these images, but there
is no guarantee that they exist or work. If I tested and hosted them
for Linodes, anyone could easily run their own copy.&lt;/p&gt;
&lt;p&gt;I began by running the installation process as normal for
FreeBSD. After the disk had FreeBSD installed on it, I rebooted into
&lt;a href="https://www.linode.com/docs/troubleshooting/rescue-and-rebuild/"&gt;Finnix&lt;/a&gt;, &lt;a href="https://wiki.archlinux.org/index.php/disk_cloning#Create_disk_image"&gt;made a compressed disk image&lt;/a&gt;, and transferred it to
an "image host" (another Linode in Fremont running an FTP
server). Then I tested the reversal process manually to make sure a
new Linode could grab the image, dd it to a disk, reboot and have a
working filesystem and networking. (This transfer occurs over private
networking to reduce bandwidth costs and thus limits Linode creation
to the datacenter of the image host, Fremont.)&lt;/p&gt;
&lt;p&gt;Then it was time to script the process. I looked into the existing
Linode API client wrappers and noticed none of them were
documented. So I took a day to write and document a good part of a
&lt;a href="https://github.com/eatonphil/python3-linode_api3"&gt;new Linode Python client&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I got to work and out came the &lt;a href="https://github.com/eatonphil/linode_deploy_experimental"&gt;linode-deploy-experimental&lt;/a&gt;
script. To run this script, you'll need an &lt;a href="https://www.linode.com/docs/platform/api/api-key/"&gt;API token&lt;/a&gt;. This
script will allow you to deploy from the hosted images (which now
include FreeBSD 11.0 and OpenBSD 6.0). Follow the example line in the
git repo and you'll have a Linode running OpenBSD or FreeBSD in
minutes.&lt;/p&gt;
&lt;p&gt;Clearly there's a lot of work to do on both this script and on the
images:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fremont datacenter has the only image host.&lt;/li&gt;
&lt;li&gt;The script does not change the default password: "password123".
You'll want to change this immediately.&lt;/li&gt;
&lt;li&gt;The script does not automatically grow the file system after
install.&lt;/li&gt;
&lt;li&gt;The TTY config for these images currently requires you to use
Glish instead of Weblish.&lt;/li&gt;
&lt;li&gt;And &lt;a href="https://github.com/eatonphil/linode_deploy_experimental/issues"&gt;more&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if many of these issues do get sorted out (I assume they will),
keep in mind that these are unofficial, unsupported images. Some
things will probably never work: backups, password reset, etc. If you
need help, you are probably limited to community support. You can also
find me with any questions (peaton on OFTC). But for me this is at
least a slight improvement on having to run through the install
process every time I need a new FreeBSD Linode.&lt;/p&gt;
&lt;p&gt;&lt;blockquote class="twitter-tweet"&gt;&lt;p dir="ltr" lang="en"&gt;Deploy FreeBSD and OpenBSD unattended on Linode &lt;a href="https://t.co/j5A46ROqNM"&gt;https://t.co/j5A46ROqNM&lt;/a&gt; &lt;a href="https://t.co/HSqrIvBMFj"&gt;https://t.co/HSqrIvBMFj&lt;/a&gt;&lt;/p&gt;&amp;mdash; Phil Eaton (@phil_eaton) &lt;a href="https://twitter.com/phil_eaton/status/840736360864591872?ref_src=twsrc%5Etfw"&gt;March 12, 2017&lt;/a&gt;&lt;/blockquote&gt; &lt;/p&gt;</description><author>Notes on software development</author><pubDate>Sat, 11 Mar 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">http://notes.eatonphil.com/deploying-freebsd-on-linode-unattended-in-minutes.html</guid></item><item><title>Go Time</title><link>https://anisse.astier.eu/go-time.html</link><description>&lt;p&gt;For the Go 1.8 Release Party in Paris I gave a lightning talk on monotonic clocks. It's essentially a talk version of the &lt;a href="https://golang.org/design/12914-monotonic"&gt;Russ Cox's design document on monotonic clocks&lt;/a&gt;, which is really well written and sourced. You should go read it !&lt;/p&gt;
&lt;p&gt;Here are the &lt;a href="https://anisse.github.io/gotime"&gt;slides export&lt;/a&gt; and their …&lt;/p&gt;</description><author>Linux Engineer's random thoughts</author><pubDate>Sun, 19 Feb 2017 01:00:00 GMT</pubDate><guid isPermaLink="true">https://anisse.astier.eu/go-time.html</guid></item><item><title>Setup up ConcourseCI 2.6.0 behind Nginx with Self Signed Certificates on Ubuntu 16.04</title><link>https://boyter.org/2017/02/setup-concourseci-2-6-0-nginx-signed-certificates-ubuntu-16-04/</link><description>&lt;p&gt;[Concourse CI][1] is a very nice continuous integration server.&lt;/p&gt;
&lt;p&gt;However for installs there are a few gotcha&amp;rsquo;s you need to keep in mind. Mostly these relate to how TLS/SSL works.&lt;/p&gt;
&lt;p&gt;The first is that while it is possible to run concourse inside Docker I found this to cause a lot of issues with workers dying and not recovering. I would suggest installing the binarys on bare machines. When I moved from a docker cluser using Amazon&amp;rsquo;s ECS to a single t2.large instance not only were builds faster but it was a far more reliable solution.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Sun, 12 Feb 2017 23:56:58 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/02/setup-concourseci-2-6-0-nginx-signed-certificates-ubuntu-16-04/</guid></item><item><title>Checkbot for Chrome: Public beta</title><link>https://www.seanw.org/blog/checkbot-for-chrome-public-beta/</link><description>Today I&amp;rsquo;m releasing the first public beta release of my new project: Checkbot for Chrome! Checkbot is a Chrome extension that crawls the pages on your site to suggest SEO, web speed and web security improvements. Checkbot aims to be a comprehensive website testing tool that gives you everything you need to identify, understand and fix website issues.
Checkbot guides you in following web best practices by helping you fix problems such as broken links, duplicate page titles, insecure login forms, redirect chains and much more.</description><author>Sean Wilson, Web app designer &amp;amp; developer, Edinburgh, UK on Sean Wilson's homepage</author><pubDate>Fri, 10 Feb 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://www.seanw.org/blog/checkbot-for-chrome-public-beta/</guid></item><item><title>Comparing Elixir and Go</title><link>https://www.brightball.com/articles/comparing-elixir-and-go</link><description>Elixir and Go have both grown significantly in popularity over the past few years, and both are often reached for by developers looking for high concurrency solutions. The two languages follow many similar principles, but both have made some core tradeoffs that affect their potential use cases. Let’s compare the two by taking a look at their backgrounds, their programming styles, and how they deal with concurrency.</description><author>Brightball Articles</author><pubDate>Tue, 07 Feb 2017 11:52:51 GMT</pubDate><guid isPermaLink="true">https://www.brightball.com/articles/comparing-elixir-and-go</guid></item><item><title>Repository overview now in searchcode server</title><link>https://boyter.org/2017/01/repository-overview-searchcode-server/</link><description>&lt;p&gt;One feature that I have wanted for a long time in searchcode server was a page which would give an overview of a repository. I wanted the overview to give a very high look at the languages used, the total number of files, estimated cost and who would be the best people to talk to.&lt;/p&gt;
&lt;p&gt;One thing that occurred to me when I started work was that it would be nice to calculate a bus factor for the repository as well. After all we all know that project managers do like to know who are the most critical contributors to any project and what the risk is.&lt;/p&gt;</description><author>Ben E. C. Boyter</author><pubDate>Mon, 30 Jan 2017 09:34:35 GMT</pubDate><guid isPermaLink="true">https://boyter.org/2017/01/repository-overview-searchcode-server/</guid></item><item><title>Simple but handy Postgres features</title><link>/2017/01/08/simple-but-handy-postgresql-features/</link><description>&lt;p&gt;It seems each week when I&amp;rsquo;m reviewing data with someone a feature comes up that they had no idea existed within Postgres. In an effort to continue documenting many of the features and functionality that are useful, here&amp;rsquo;s a list of just a few that you may find handy the next time your working with your data.&lt;/p&gt;
&lt;h3 id="psql-and-e"&gt;
&lt;div&gt;
Psql, and \e
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;This one I&amp;rsquo;ve &lt;a href="http://www.craigkerstiens.com/2013/02/13/How-I-Work-With-Postgres/"&gt;covered before&lt;/a&gt;, but it&amp;rsquo;s worth restating. Psql is a great editor that already comes with Postgres. If you&amp;rsquo;re comfortable on the CLI you should consider giving it a try. You can even setup you&amp;rsquo;re own &lt;code&gt;.psqlrc&lt;/code&gt; for it so that it&amp;rsquo;s well customized to your liking. In particular turning &lt;code&gt;\timing&lt;/code&gt; on is especially useful. But even with all sorts of customization if you&amp;rsquo;re not aware that you can use your preferred editor by using &lt;code&gt;\e&lt;/code&gt; then you&amp;rsquo;re missing out. This will allow you to open up the last run query, edit it, save–and then it&amp;rsquo;ll run for you. Vim, Emacs, even Sublime text works just take your pick by setting your &lt;code&gt;$EDITOR&lt;/code&gt; variable.&lt;/p&gt;
&lt;h3 id="watch"&gt;
&lt;div&gt;
Watch
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;Ever sit at a terminal running a query over and over to see if something on your system changed? If you&amp;rsquo;re debugging something whether locally or even live in production, watching data change can be key to figuring out. Instead of re-running your query you could simply use the &lt;code&gt;\watch&lt;/code&gt; command in Postgres, this will re-run your query automatically every few seconds.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; now() &lt;span style="color: #f92672;"&gt;-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; query_start,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #66d9ef;"&gt;state&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; query
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; pg_stat_activity
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #960050; background-color: #1e0010;"&gt;\&lt;/span&gt;watch
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="jsonb-pretty-print"&gt;
&lt;div&gt;
JSONB pretty print
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;I love &lt;a href="https://www.citusdata.com/blog/2016/07/14/choosing-nosql-hstore-json-jsonb/"&gt;JSONB&lt;/a&gt; as a datatype. Yes, in cases it won&amp;rsquo;t be the &lt;a href="http://blog.heapanalytics.com/when-to-avoid-jsonb-in-a-postgresql-schema/"&gt;optimal&lt;/a&gt; for performance (though at times it can be perfectly fine). If I&amp;rsquo;m hitting some API that returns a ton of data, I&amp;rsquo;m usually not using all of it right away. But, you never know when you&amp;rsquo;ll want to use the rest of it. I use &lt;a href="https://www.clearbit.com"&gt;Clearbit&lt;/a&gt; this way today, and for safety sake I save all the JSON result instead of de-normalizing it. Unfortunately, when you query this in Postgres you get one giant compressed text of JSON. Yes, you could pipe out to something like jq, or you could simply use Postgres built in function to make it legible:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-sql"&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;SELECT&lt;/span&gt; jsonb_pretty(clearbit_response)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #66d9ef;"&gt;FROM&lt;/span&gt; lookup_data;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; jsonb_pretty
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;-------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt;&lt;span style="color: #75715e;"&gt;&lt;/span&gt; &lt;span style="color: #960050; background-color: #1e0010;"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"person"&lt;/span&gt;: &lt;span style="color: #960050; background-color: #1e0010;"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"id"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"063f6192-935b-4f31-af6b-b24f63287a60"&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"bio"&lt;/span&gt;: &lt;span style="color: #66d9ef;"&gt;null&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"geo"&lt;/span&gt;: &lt;span style="color: #960050; background-color: #1e0010;"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"lat"&lt;/span&gt;: &lt;span style="color: #ae81ff;"&gt;37&lt;/span&gt;.&lt;span style="color: #ae81ff;"&gt;7749295&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"lng"&lt;/span&gt;: &lt;span style="color: #f92672;"&gt;-&lt;/span&gt;&lt;span style="color: #ae81ff;"&gt;122&lt;/span&gt;.&lt;span style="color: #ae81ff;"&gt;4194155&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"city"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"San Francisco"&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"state"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"California"&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"country"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"United States"&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"stateCode"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"CA"&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"countryCode"&lt;/span&gt;: &lt;span style="color: #e6db74;"&gt;"US"&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #960050; background-color: #1e0010;"&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; &lt;span style="color: #e6db74;"&gt;"name"&lt;/span&gt;: &lt;span style="color: #960050; background-color: #1e0010;"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display: flex;"&gt;&lt;span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="importing-my-data-into-google"&gt;
&lt;div&gt;
Importing my data into Google
&lt;/div&gt;
&lt;/h3&gt;
&lt;p&gt;This one isn&amp;rsquo;t Postgres specific, but I use it on a weekly basis and it&amp;rsquo;s key for us at &lt;a href="https://www.citusdata.com"&gt;Citus&lt;/a&gt;. If you use something like Heroku Postgres, dataclips is an extremely handy feature that lets you have a real-time view of a query and the results of it, including an anonymous URL you can it for it. At Citus much like we did at Heroku Postgres we have a dashboard in google sheets which pulls in this data in real-time. To do this simple select a cell then put in: &lt;code&gt;=importdata(&amp;quot;pathtoyourdataclip.csv&amp;quot;)&lt;/code&gt;. Google will import any data using this as long as it&amp;rsquo;s in CSV form. It&amp;rsquo;s a great lightweight way to build out a dashboard for your business without rolling your own complicated dashboarding or building out a complex ETL pipeline.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m sure I&amp;rsquo;m missing a ton of the smaller features that you use on a daily basis. Let me know &lt;a href="https://www.twitter.com/craigkerstiens"&gt;@craigkerstiens&lt;/a&gt; the ones I forgot that you feel should be listed.&lt;/p&gt;</description><author>CRAIG KERSTIENS</author><pubDate>Sun, 08 Jan 2017 22:55:56 GMT</pubDate><guid isPermaLink="true">/2017/01/08/simple-but-handy-postgresql-features/</guid></item><item><title>A metaphor</title><link>https://rjp.is/blogging/posts/a-metaphor-2/</link><description>In which we dip our toe into politics.</description><author>infrequent oscillations</author><pubDate>Sat, 07 Jan 2017 17:21:55 GMT</pubDate><guid isPermaLink="true">https://rjp.is/blogging/posts/a-metaphor-2/</guid></item><item><title>Looking back on 2016, and forward to 2017</title><link>https://benovermyer.com/blog/2017/01/looking-back-on-2016-and-forward-to-2017/</link><description>&lt;p&gt;2016 was a rough year. We lost a lot of good people; the loss of Carrie Fisher in particular hit me hard. Politically, the year was disappointing. But 2016 was also a good year for me personally. Doors and eyes opened. 2017 should continue that trend, if I read the signs correctly.&lt;/p&gt;
&lt;h1 id="victories-in-2016"&gt;Victories in 2016&lt;/h1&gt;
&lt;p&gt;I returned to Silver Gryphon Games. While this has not borne fruit yet, it marked a commitment that's important to me. I lost a lot of weight in the early part of 2016. I followed a paleo diet, practiced parkour, and started to see increased energy levels and a better self image. I learned what it meant to be a manager, but not until later in the year. For the first part of the year, I was a “manager” but didn't fully understand the difference between a technical lead and a manager. In November, it finally clicked: managers focus on the big picture. Technical leads bridge the gap between big picture and technical execution. That realization gave me new energy and a powerful sense of purpose.&lt;/p&gt;
&lt;h1 id="challenges-in-2016"&gt;Challenges in 2016&lt;/h1&gt;
&lt;p&gt;One of the biggest stressors for me in 2016 was personal finances. I moved out of my old apartment earlier than I should have. For two months, I was paying for two apartments. I misjudged my cash flow and missed payments on some things for the first time in over five years. Weight and diet were also challenges. While in the first quarter of the year I lost over thirty pounds, the last quarter of the year saw a slight reversal. I gained back ten of those pounds. My diet changed from paleo-ish to unrestricted. My drinking became even more of a problem in the latter half of the year. For the first time in my life, I had a couple days where I couldn't remember large chunks of the previous night. It feels like my memory generally has gotten worse, though I don't have data to support that, or even to suggest that the two are connected.&lt;/p&gt;
&lt;h1 id="goals-for-the-new-year"&gt;Goals for the New Year&lt;/h1&gt;
&lt;p&gt;I'm going to regain my budgetary sense from early 2016 and put significant effort towards paying down debt. This is my primary goal in 2017. I will return to a controlled diet. I'm cutting back on eating out. I love cooking, so this isn't that difficult for me. It's going to require paying attention, though. The big difficulty here is going to be work lunches, since I don't care for sandwiches or microwaved leftovers. Getting my drinking under control is going to be both simple and difficult. In 2016, I drank most often when at home playing video games. Since those two habits are so intertwined, I will need to find a way to sever the connection. In general, I believe I'll be able to succeed at my goals in 2017. I have great hope for the future.&lt;/p&gt;</description><author>Ben Overmyer's Site</author><pubDate>Sun, 01 Jan 2017 02:00:00 GMT</pubDate><guid isPermaLink="true">https://benovermyer.com/blog/2017/01/looking-back-on-2016-and-forward-to-2017/</guid></item></channel></rss>