<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>relaxdiego</title><link>https://relaxdiego.com/</link><description>Recent content on relaxdiego</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 20 Aug 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://relaxdiego.com/rss.xml" rel="self" type="application/rss+xml"/><item><title>KubeVirt on Autoscaling Baremetal Nodes</title><link>https://relaxdiego.com/2023/08/kubevirt-cas-baremetal.html</link><pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2023/08/kubevirt-cas-baremetal.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Authored by &lt;a href="https://github.com/jkinred"&gt;Jonathan Kinred&lt;/a&gt; and &lt;a href="https://github.com/pmyjavec"&gt;Paul Myjavec&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;For this article, we&amp;rsquo;ll learn about the process of setting up
&lt;a href="https://kubevirt.io/"&gt;KubeVirt&lt;/a&gt; with &lt;a href="https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md"&gt;Cluster
Autoscaler&lt;/a&gt;
on EKS. In addition, we&amp;rsquo;ll be using bare metal nodes to host KubeVirt VMs.&lt;/p&gt;
&lt;h2 id="required-base-knowledge"&gt;Required Base Knowledge&lt;/h2&gt;
&lt;p&gt;This article will talk about how to make various software systems work together
but introducing each one in detail is outside of its scope. Thus, you must already:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Know how to administer a Kubernetes cluster;&lt;/li&gt;
&lt;li&gt;Be familiar with AWS, specifically IAM and EKS; and&lt;/li&gt;
&lt;li&gt;Have some experience with KubeVirt.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="companion-code"&gt;Companion Code&lt;/h2&gt;
&lt;p&gt;All the code used in this article may also be found at
&lt;a href="https://github.com/relaxdiego/kubevirt-cas-baremetal"&gt;github.com/relaxdiego/kubevirt-cas-baremetal&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>A Case for Monorepos</title><link>https://relaxdiego.com/2023/07/a-case-for-monorepos.html</link><pubDate>Sun, 02 Jul 2023 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2023/07/a-case-for-monorepos.html</guid><description>&lt;p&gt;For some time now, we&amp;rsquo;ve been living in the era of microservices. An era where
a strict separation of concerns is the norm. Where it is difficult to
circumvent the rule by way of putting each microservice in its own repository
and execution environment. This has, in many ways, permitted us to be more
thoughtful about our system designs, allowing us to avoid the &amp;ldquo;big ball of mud&amp;rdquo;
problem to a significant extent. However, this era of isolation has also
presented a unique set of challenges, specifically in the aspect of code reuse.&lt;/p&gt;</description></item><item><title>CI/CD and Shared Environments</title><link>https://relaxdiego.com/2022/04/sharing-environments-effectively.html</link><pubDate>Sun, 24 Apr 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/04/sharing-environments-effectively.html</guid><description>&lt;p&gt;Dev/QA/Staging/Production environments are shared resources and, like
any shared resource, access to them must be managed; otherwise environment
corruption may occur, resulting in loss of data and precious engineering time.&lt;/p&gt;
&lt;p&gt;Take for example this scenario where we have a pipeline that deploys
to an environment:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://relaxdiego.com/assets/images/environment-sharing/deploy-1.png" alt="PE #1 deploys to environment" width="451" height="369" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Usually, a &lt;strong&gt;pipeline execution (PE)&lt;/strong&gt; includes running database migrations, collating
assets, adjusting load balancers, running automated tests
against the newly deployed build, and so on. What this means is that this
process can take a few seconds to a few minutes. Let&amp;rsquo;s now consider what
will happen when, during the period when PE #1 is still using the environment,
another PE comes into play:&lt;/p&gt;</description></item><item><title>If You Want to Work in DevOps</title><link>https://relaxdiego.com/2022/03/if-you-want-to-work-in-devops.html</link><pubDate>Mon, 28 Mar 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/03/if-you-want-to-work-in-devops.html</guid><description>&lt;p&gt;If you’re hoping to land a job that has &amp;ldquo;DevOps&amp;rdquo; in the title,
understand that your overarching responsibility is to ensure that
the organization&amp;rsquo;s software service delivery process is optimal and
that the availability of each service meets user expectations.&lt;/p&gt;
&lt;p&gt;To achieve that, you must ensure that the infrastructure supporting
each service is robust. This is where your systems design skills come
into play.&lt;/p&gt;
&lt;p&gt;&amp;hellip;and, should a service or its infrastructure experience an unhandled
error, that you have instrumentation in place to let you know of it
immediately. This is what alerting is for.&lt;/p&gt;</description></item><item><title>Reduce Your CI/CD Config Sprawl</title><link>https://relaxdiego.com/2022/03/reduce-cicd-config-sprawl.html</link><pubDate>Tue, 01 Mar 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/03/reduce-cicd-config-sprawl.html</guid><description>&lt;p&gt;If you’re still experiencing the pain of CircleCI config.yml copypasta
even after using orbs, here’s a possible next step in your evolution.&lt;/p&gt;
&lt;h2 id="transcript"&gt;Transcript&lt;/h2&gt;
&lt;p&gt;In CircleCI, your workflow configuration is stored alongside your code in
&lt;code&gt;.circleci/config.yml&lt;/code&gt;. This makes it easier to synchronize your CI/CD
workflow with your code.&lt;/p&gt;
&lt;p&gt;However, this also comes with disadvantages. For one, it can result in
duplicate workflow and job definitions. This is especially problematic
if you have multiple repositories that have the same workflow. For
example, let&amp;rsquo;s say you have 3 distinct applications all written with the
FastAPI framework and deployed to Kubernetes. In this case you&amp;rsquo;d have to
make sure that their config files don&amp;rsquo;t diverge from one another. Otherwise
you&amp;rsquo;ll have to frequently re-learn how each application is built and
deployed.&lt;/p&gt;</description></item><item><title>TDD but for Networking</title><link>https://relaxdiego.com/2022/02/tdd-but-for-networking.html</link><pubDate>Fri, 25 Feb 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/02/tdd-but-for-networking.html</guid><description>&lt;p&gt;Tired of spending precious time trying to debug why one AWS resource
can&amp;rsquo;t talk to another? Add &lt;a href="https://docs.aws.amazon.com/vpc/latest/reachability/what-is-reachability-analyzer.html"&gt;VPC Reachability Analyzer&lt;/a&gt;
to your toolkit, mix it up with some Test-Driven Development (TDD)
workflow and take back some of your sanity!&lt;/p&gt;
&lt;h2 id="write-the-test-create-the-path-watch-it-fail"&gt;&lt;del&gt;Write the Test&lt;/del&gt; Create the Path, Watch it Fail&amp;hellip;&lt;/h2&gt;
&lt;p&gt;Create the path to analyze before your networking config is fully configured
then see helpful error messages like the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;destination&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;arn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;arn:aws:ec2:xx-xxxx-x:xxxxxxxx:vpc-peering-connection/pcx-xxxxxxxxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pcx-xxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;explanationCode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;NO_ROUTE_TO_DESTINATION&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;routeTable&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;arn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;arn:aws:ec2:xx-xxxx-x:xxxxxxxx:route-table/rtb-xxxxxxxxxxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;rtb-xxxxxxxxxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;vpc&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;arn&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;arn:aws:ec2:xx-xxxx-x:xxxxxxxx:vpc/vpc-xxxxxxxxxxxx&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;vpc-xxxxxxxxxxxxxx&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="write-the-code-configure-the-network-watch-it-pass"&gt;&lt;del&gt;Write the Code&lt;/del&gt; Configure the Network, Watch it Pass&amp;hellip;&lt;/h2&gt;
&lt;p&gt;Once you&amp;rsquo;ve fixed the errors above and re-run the analysis, you&amp;rsquo;ll get
the following report:&lt;/p&gt;</description></item><item><title>Auto-testing code snippets in my blog</title><link>https://relaxdiego.com/2022/02/autotest-code-snippets.html</link><pubDate>Wed, 16 Feb 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/02/autotest-code-snippets.html</guid><description>&lt;p&gt;I finally got around to auto-testing the code snippets in my blog posts.
As of today, the process of writing a blog post with code snippets goes
like this:&lt;/p&gt;
&lt;h3 id="step-1-run-the-background-services"&gt;Step 1: Run the background services&lt;/h3&gt;
&lt;p&gt;First I&amp;rsquo;ll run &lt;a href="https://ddollar.github.io/foreman/"&gt;Foreman&lt;/a&gt; locally while in my
blog&amp;rsquo;s dir. Foreman starts up three processes in the background: a
&lt;a href="https://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; server, my résumé autorenderer, and
a snippets autotester (the topic of this post). Each subprocess'
stdout and stderr are printed by Foreman, with each line properly prefixed
such that it says which process printed out which line:&lt;/p&gt;</description></item><item><title>Dealing with ISO 8601 in Python</title><link>https://relaxdiego.com/2022/02/python-and-iso8601.html</link><pubDate>Mon, 14 Feb 2022 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2022/02/python-and-iso8601.html</guid><description>&lt;p&gt;ISO 8601 datetime strings are great but they come with surprising
special conditions that you may need to consider when the datetime
strings come from an external client. There are third-party libraries
out there that can ease your burden but, for times when you don&amp;rsquo;t have
the luxury of using anything but stock Python, read on.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;NOTE: All code snippets below are available on &lt;a href="https://github.com/relaxdiego/relaxdiego.github.com/tree/master/snippets/iso8601"&gt;Github&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with the simplest case.&lt;/p&gt;</description></item><item><title>Rediscovering DevOps</title><link>https://relaxdiego.com/2021/05/rediscovering-devops.html</link><pubDate>Fri, 14 May 2021 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2021/05/rediscovering-devops.html</guid><description>&lt;h2 id="preamble"&gt;Preamble&lt;/h2&gt;
&lt;p&gt;This article attempts to cut through the cruft and re-discover what
it really means to practice DevOps in your organization. It does this
by reviewing the three principles of DevOps: systems throughput,
fast feedback, and continuous learning. It further re-inforces these
principles with two tried and tested engineering concepts: The Theory of
Constraints and Control Theory.&lt;/p&gt;
&lt;h2 id="tldr"&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;DevOps is just Process Engineering specialized for software
delivery. The wealth of knowledge built up by Process and Industrial
Engineering will prove useful in delivering software products.&lt;/p&gt;</description></item><item><title>Make Your Old Printer Airprint Capable</title><link>https://relaxdiego.com/2021/01/airprint-server-with-pi-zero-w.html</link><pubDate>Fri, 22 Jan 2021 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2021/01/airprint-server-with-pi-zero-w.html</guid><description>&lt;p&gt;Learn how to turn a $10 Raspberry Pi Zero into an Airprint server that
allows you to print wirelessly from your PC, Mac, or smartphone.&lt;/p&gt;
&lt;center&gt;
&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/2bBoKt-mZh8" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/center&gt;
&lt;p&gt;Links to things mentioned in the video:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.raspberrypi.org"&gt;Official Raspberry Pi Website&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.techradar.com/how-to/computing/how-to-turn-the-raspberry-pi-into-a-wireless-printer-server-1312717"&gt;How to turn the Raspberry Pi into a wireless printer server&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.amazon.com/dp/B00N9S9Z0G"&gt;USB to Micro USB adapter&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.amazon.com/dp/B00B2HOS08"&gt;Mini HDMI to HDMI Adapter&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://raspberrypi.stackexchange.com/questions/63519/power-consumption-of-pi-zero-w"&gt;Power consumption of Pi Zero W&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Analyzing an Apache Log File</title><link>https://relaxdiego.com/2019/01/bash-analytics.html</link><pubDate>Thu, 24 Jan 2019 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2019/01/bash-analytics.html</guid><description>&lt;p&gt;Pop quiz, hot shot! You need to quickly get an idea of the top 5 clients IPs
of your website grouped by path and HTTP status code but only between 6PM and
7PM and only for requests with HTTP status code 40x. Quick! What tools do
you pick up? Do you use go, python, C? What about the framework? And how do
you onboard the rest of your team?&lt;/p&gt;
&lt;p&gt;Slow down, take a deep breath. For this scenario, you don&amp;rsquo;t need anything more
than Bash and friends. To get an idea of how to do that, try out this 60-liner
bash script to get the data I mentioned above.&lt;/p&gt;</description></item><item><title>Keeping Continuous Integration Continuously Integrating</title><link>https://relaxdiego.com/2018/08/keeping-continuous-integration-continuous.html</link><pubDate>Thu, 16 Aug 2018 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2018/08/keeping-continuous-integration-continuous.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;OUTDATED ARTICLE&lt;/strong&gt;: This article has been superseded by a
&lt;a href="https://relaxdiego.com/2022/04/sharing-environments-effectively.html"&gt;newer one&lt;/a&gt;. Please
refer to that article instead.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Have you ever had to deal with the situation where your CI lags further
and further as the day progresses because more builds are getting queued
up for your long-running tests? Some of you may have tried to solve that
by firing up multiple test environments and then assigning different builds
to these different environments thereby achieving some parallelism but this
can get very costly. Some of you may have tried converting your long-running
tests into nightly jobs but this means you won&amp;rsquo;t get timely reports on
broken builds.&lt;/p&gt;</description></item><item><title>Jenkins on Jenkins - Unit Testing Shared Libraries</title><link>https://relaxdiego.com/2018/02/jenkins-on-jenkins-shared-libraries.html</link><pubDate>Sun, 04 Feb 2018 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2018/02/jenkins-on-jenkins-shared-libraries.html</guid><description>&lt;p&gt;If you&amp;rsquo;ve ever worked with Jenkins shared libraries, you know that they&amp;rsquo;re a
great way to simplify your Jenkins Pipeline DSL scripts by abstracting out
common code to a function. For example, this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-groovy" data-lang="groovy"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Prep&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Create the release ID for this build
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;readFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;VERSION&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;trim&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;buildID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BUILD_ID&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;shortSha&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GIT_COMMIT&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;take&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;prMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CHANGE_ID&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;pr${env.CHANGE_ID}.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;releaseID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;${version}+${prMetadata}.b${buildID}.${shortSha}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Could become this:&lt;/p&gt;</description></item><item><title>Canal and Calico Networking for k8s</title><link>https://relaxdiego.com/2017/12/canal-and-calico.html</link><pubDate>Wed, 13 Dec 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/12/canal-and-calico.html</guid><description>&lt;p&gt;Here&amp;rsquo;s a quick diagram on how Canal and Calico networking is implemented
in Kubernetes. If the image below is hard to read, &lt;a href="https://docs.google.com/drawings/d/1vEMtzIzaXb7UFwfJJ5utEStqPw9cT3wQg3Tut1dP1a8/edit?usp=sharing"&gt;here&amp;rsquo;s a direct link&lt;/a&gt;.&lt;/p&gt;
&lt;img src="https://docs.google.com/drawings/d/e/2PACX-1vQGTLNcWY-Tb7v2hOS5OxhMiWe7rUpB09n4Cb9ndigFBQUFjapWjInkMYk29Rp1XVK5E_Zj-Fyj4bg6/pub?w=1310&amp;amp;h=1592"&gt;
&lt;p&gt;NOTE: While I&amp;rsquo;ve depicted the iptables rules and routes as boxes in these
diagrams, note that they&amp;rsquo;re not really implemented as Linux devices. Rather,
I just wanted to show how the routes are applied to the packets as they
make there way to and fro the actual devices.&lt;/p&gt;</description></item><item><title>Visualizing Brooks' Law</title><link>https://relaxdiego.com/2017/11/visualizing-brooks-law.html</link><pubDate>Mon, 27 Nov 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/11/visualizing-brooks-law.html</guid><description>&lt;p&gt;&amp;ldquo;Adding human resources to a late software makes it later&amp;rdquo;
&lt;br&gt;&amp;ndash; &lt;a href="https://en.wikipedia.org/wiki/Fred_Brooks"&gt;Fred Brooks&lt;/a&gt;,
&lt;a href="https://read.amazon.com/kp/embed?asin=B00B8USS14&amp;amp;preview=newtab&amp;amp;linkCode=kpe&amp;amp;ref_=cm_sw_r_kb_dp_yJ-gAb29R21FJ"&gt;The Mythical Man-Month&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hear this truism regularly and I can also feel its effects whenever
new members join a team I&amp;rsquo;m in but I&amp;rsquo;ve never really given it much
thought until now. In this blog post, I&amp;rsquo;ll attempt to dissect and
visualize Brooks&amp;rsquo; Law to find out what it is exactly about adding
new team members that negatively affects short-term team progress.&lt;/p&gt;</description></item><item><title>September SF k8s Lightning Talk</title><link>https://relaxdiego.com/2017/11/sfk8s-lightning-talk.html</link><pubDate>Thu, 02 Nov 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/11/sfk8s-lightning-talk.html</guid><description>&lt;p&gt;Here&amp;rsquo;s my lightning talk from last September&amp;rsquo;s SF Kubernetes Meetup.
Thanks to &lt;a href="https://stackpoint.io/"&gt;Stack Point Cloud&lt;/a&gt;, &lt;a href="https://bitnami.com/"&gt;Bitnami&lt;/a&gt;,
and &lt;a href="https://www.weave.works/"&gt;Weave Works&lt;/a&gt; for making this event happen!&lt;/p&gt;
&lt;p&gt;UPDATE: Since that lightning talk, we&amp;rsquo;ve moved away from the VM-based
setup and started investigating other methods that still satisfy the
3 hard requirements mentioned in the talk.&lt;/p&gt;
&lt;center&gt;
&lt;iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/b8r0LmbF-rM" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;
&lt;/center&gt;</description></item><item><title>A Framework for Qualitatively Evaluating an Incubator</title><link>https://relaxdiego.com/2017/11/business-incubation-framework.html</link><pubDate>Wed, 01 Nov 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/11/business-incubation-framework.html</guid><description>&lt;p&gt;While drafting a series on CI/CD these past few weeks, I came across
an old research paper that I wrote back in my Master of Management program
at the &lt;a href="http://www.anu.edu.au/"&gt;Australian National University&lt;/a&gt;* in
Canberra. My research was focused on creating a wholistic framework for
evaluating the efficacy of a business incubator within a community.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s still in its nascent form to this day since I haven&amp;rsquo;t had the chance
to continue working on it but I&amp;rsquo;m sharing it here, warts and all, in case
anyone might find this useful. If you do end up basing your work on it
or further improve it, please don&amp;rsquo;t hesitate to contact me. I&amp;rsquo;d love to
see how much further this framework can go!&lt;/p&gt;</description></item><item><title>Introducing the Magic of Computing to Kids</title><link>https://relaxdiego.com/2017/10/coding-kids.html</link><pubDate>Fri, 20 Oct 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/10/coding-kids.html</guid><description>&lt;p&gt;Today, I spent my morning introducing the magic of programming to a
class of 2nd graders and it was amazing. It was also one of the more
nerve-racking experiences as far as preperations go. I was so nervous
I spent the better portion of my morning (starting at 6AM) researching
and preparing!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://photos.google.com/share/AF1QipMDAOUY4Y8u0hH8jwSQRf2NZutmOSARt0nXgG_BVgwBA8snGSEbuDH9u4PK7v5vSQ?key=RndkYk92UmFLX0dvUG1FRHZaX1V4ak5mTDJDMEZB&amp;amp;source=ctrlq.org"&gt;&lt;img src="https://relaxdiego.com/assets/images/kids-coding-001.png" alt="Reading through the lesson notes before the session" width="560" height="500" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Having the &lt;a href="http://scratched.gse.harvard.edu/guide/"&gt;Creative Computing&lt;/a&gt;
site was a huge thing because it pretty much wrote all the material
that I needed and more! For a 45-minute session though, I only had
time to get them excited about Scratch and to try out a few very simple
exercises. Basically, I boiled down the session to the following activities:&lt;/p&gt;</description></item><item><title>Fully Automated Blog and Resume</title><link>https://relaxdiego.com/2017/09/fully-automated-blog.html</link><pubDate>Sat, 23 Sep 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/09/fully-automated-blog.html</guid><description>&lt;p&gt;I finally got around to fully automating my blog generation including
the resume rendering part (both HTML and PDF formats).
&lt;a href="https://github.com/relaxdiego/relaxdiego.github.com/commit/6b5b222ab3fa7cd6288111abfe99b79c13fbd665"&gt;These&lt;/a&gt;
&lt;a href="https://github.com/relaxdiego/relaxdiego.github.com/commit/de069a6fb8e5f657257cbeea6bfd0509584b94e4"&gt;are&lt;/a&gt;
&lt;a href="https://github.com/relaxdiego/relaxdiego.github.com/commit/0dab5cea040989f8220f16c555e60da0707c89af"&gt;the&lt;/a&gt;
&lt;a href="https://github.com/relaxdiego/relaxdiego.github.com/commit/1ad70fa95b72ae9bca80f299503a002189c95727"&gt;changes&lt;/a&gt;
that made that happen.&lt;/p&gt;
&lt;p&gt;So now my workflow just involves starting &lt;a href="https://github.com/ddollar/foreman"&gt;&lt;strike&gt;Foreman&lt;/strike&gt;&lt;/a&gt;
&lt;a href="https://github.com/mattn/goreman"&gt;Goreman&lt;/a&gt; in one terminal session while I work
inside Vim in another session. &lt;a href="https://github.com/tmux/tmux/wiki"&gt;tmux&lt;/a&gt;, of
course, makes all of that easy peasy.&lt;/p&gt;
&lt;p&gt;Automation rocks.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://relaxdiego.com/assets/images/automated-blog.png" alt="Fully Automated Blog Workflow" width="2344" height="1770" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Product Radial Evaluation Framework (P-REF)</title><link>https://relaxdiego.com/2017/09/esrf.html</link><pubDate>Sun, 03 Sep 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/09/esrf.html</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This post is a load of bullcrap. Don&amp;rsquo;t use it. I&amp;rsquo;m just keeping
it online for historical purposes&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So you&amp;rsquo;ve come across what you think is the right solution to a market
problem and now you&amp;rsquo;ve gone ahead and built a team to develop it. How can
you monitor that you and your team are developing the solution the right way?
This framework can potentially help you determine if you&amp;rsquo;ve covered all
your bases and if there are problem spots that you need to address before
going any further.&lt;/p&gt;</description></item><item><title>A Team's API Contract</title><link>https://relaxdiego.com/2017/08/team-api-contract.html</link><pubDate>Wed, 30 Aug 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/08/team-api-contract.html</guid><description>&lt;p&gt;This is an old email that I sent to my teammates. I&amp;rsquo;m sharing this for
posterity and also because I think it applies to any software team.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Hi team!&lt;/p&gt;
&lt;p&gt;I hope you’ve had a good week this week and, if not, well it’s a Friday!&lt;/p&gt;
&lt;p&gt;I wanted to talk to you about the “API contract” between you and me
because it facilitates the team’s morale and productivity. Before I
proceed, I want you to fully understand that what I write below IS NOT
law. Instead, consider it as a conversation starter: “This is how I see
things. Tell me if it’s different from what you are seeing.”&lt;/p&gt;</description></item><item><title>HA Kubernetes Outside the Cloud</title><link>https://relaxdiego.com/2017/08/hakube.html</link><pubDate>Sat, 26 Aug 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/08/hakube.html</guid><description>&lt;p&gt;Let&amp;rsquo;s say you want to install a piece of software on your desktop. Let&amp;rsquo;s
make it more fun and say you want to install the latest, coolest, most
awesomest (yes, I just made that word a thing!) video game. What&amp;rsquo;s the
first thing you want to check before you buy it? You normally would check
the system requirements. How much CPU power does it need? Do you need to
buy more RAM? Will it be fine on HDDs (spinning disks) or does it require
SSDs? Should you install (and therefore maintain/operate) some liquid-based
cooling mechanism on your machine? These are very important questions to
ask because it will affect your overall gaming experience. Depending on
your preferences, you might get by with the minimum requirements or you
might want to soup up your gear before proceeding. It&amp;rsquo;s really a function
of &amp;ldquo;how much of the total experience do you want to have?&amp;rdquo; and &amp;ldquo;how much
of it can you afford?&amp;rdquo;&lt;/p&gt;</description></item><item><title>On Sizing Stories</title><link>https://relaxdiego.com/2017/07/on-sizing-stories.html</link><pubDate>Sun, 23 Jul 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/07/on-sizing-stories.html</guid><description>&lt;p&gt;Let&amp;rsquo;s take a quick break from coding and talk about planning in a Scrum-based
team. Specifically, let&amp;rsquo;s talk about sizing or assigning points to stories.&lt;/p&gt;
&lt;p&gt;Even after more than 8 years* of practicing Scrum, I still encounter teams who
find it hard to grasp the idea of story points and, unfortunately, fall back
to the old ways of equating a point to a certain number of hours or days. I
can&amp;rsquo;t blame them though because, when I was just starting with Scrum, I&amp;rsquo;ve read
so many conflicting publications on this topic and, combined with all the other
&amp;ldquo;alien&amp;rdquo; concepts introduced by Agile, it took a while to wrap my head around it.
The &amp;ldquo;aha!&amp;rdquo; moment happened for me after I read &lt;a href="https://pragprog.com/book/jtrap/the-agile-samurai"&gt;this book&lt;/a&gt;
about 7 years ago and what I&amp;rsquo;m about to share below is largely based off of that.&lt;/p&gt;</description></item><item><title>Templating and Testing With Bash</title><link>https://relaxdiego.com/2017/05/templating-and-testing-with-bash.html</link><pubDate>Fri, 12 May 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/05/templating-and-testing-with-bash.html</guid><description>&lt;p&gt;I needed to write a simple templating system in Bash and wanted to do
it with TDD helping me along the way. Here&amp;rsquo;s what I came up with.&lt;/p&gt;
&lt;h2 id="prior-art"&gt;Prior Art&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not the first person to do this. I drew my inspiration from the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.haleby.se/2015/11/20/simple-templating-engine-in-bash/"&gt;http://code.haleby.se/2015/11/20/simple-templating-engine-in-bash/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://blog.lavoie.sl/2012/11/simple-templating-system-using-bash.html"&gt;http://blog.lavoie.sl/2012/11/simple-templating-system-using-bash.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="my-requirements"&gt;My Requirements&lt;/h2&gt;
&lt;p&gt;I wanted to be able to write a template script that contained placeholder values
to be interpolated by my bash templating system as well as regular variables
that should be left untouched. For example:&lt;/p&gt;</description></item><item><title>Load Balancing Sockets</title><link>https://relaxdiego.com/2017/02/load-balancing-sockets.html</link><pubDate>Fri, 03 Feb 2017 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2017/02/load-balancing-sockets.html</guid><description>&lt;p&gt;If you need to write a service or agent that can cater to multiple
requests in parallel coming in from a single socket, you want to have
multiple subprocesses ready to cater to those requests in parallel.
But the question now is how do you ensure the requests are load balanced
across those subprocesses? Do you build a &amp;ldquo;Master&amp;rdquo; process that takes
care of load balancing, handing off those requests to the subprocesses
as needed?&lt;/p&gt;</description></item><item><title>Fully-tested Ansible Modules from AnsibleFest NY 2016</title><link>https://relaxdiego.com/2016/10/ansiblefest-ny-video.html</link><pubDate>Mon, 24 Oct 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/10/ansiblefest-ny-video.html</guid><description>&lt;iframe allowtransparency="true" frameborder="0" scrolling="no" class="wistia_embed" name="wistia_embed" src="https://fast.wistia.com/embed/iframe/qe6c0oe4q7" width="770" height="433.125"&gt;&lt;/iframe&gt;</description></item><item><title>Writing Ansible Modules Part 5 - Helpful Resources</title><link>https://relaxdiego.com/2016/10/writing-ansible-modules-005.html</link><pubDate>Sat, 01 Oct 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/10/writing-ansible-modules-005.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is part 5 of a series of articles. For other parts, see
&lt;a href="https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html"&gt;the introductory article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="im-so-proud-of-you"&gt;I&amp;rsquo;m So Proud of You!&lt;/h2&gt;
&lt;p&gt;You did a rockin&amp;rsquo; job finishing this series! Now it&amp;rsquo;s time for you to continue
the journey on your own but not necessarily alone. Here are some resources that
will help you become an effective module developer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="http://docs.ansible.com/ansible/developing_modules.html#module-checklist"&gt;The official module checklist&lt;/a&gt;&lt;/strong&gt; -
This is a very useful set of items to review especially just before you
submit code upstream. Keep it in your bookmarks!&lt;/p&gt;</description></item><item><title>Writing Ansible Modules Part 4 - Submitting Code Upstream</title><link>https://relaxdiego.com/2016/09/writing-ansible-modules-004.html</link><pubDate>Fri, 30 Sep 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/09/writing-ansible-modules-004.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is part 4 of a series of articles. For other parts, see
&lt;a href="https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html"&gt;the introductory article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="time-to-push-to-origin"&gt;Time To Push to Origin!&lt;/h2&gt;
&lt;p&gt;Run the following from the &lt;strong&gt;ansible repo&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git add cloud/
$ git add test 
$ git commit -m &amp;quot;First module including tests&amp;quot;
$ git push origin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Head on over to your Github fork and create a pull request
out of the commit you just pushed. Once the PR has been created, copy the PR&amp;rsquo;s
URL to your clipboard since you will need to reference it from the next PR we
will create next.&lt;/p&gt;</description></item><item><title>Writing Ansible Modules Part 3 - Complete the Module</title><link>https://relaxdiego.com/2016/09/writing-ansible-modules-003.html</link><pubDate>Thu, 29 Sep 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/09/writing-ansible-modules-003.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is part 3 of a series of articles. For other parts, see
&lt;a href="https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html"&gt;the introductory article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="lets-implement-fetch"&gt;Let&amp;rsquo;s Implement fetch()&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s write the test:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nd"&gt;@patch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ansible.modules.cloud.somebodyscomputer.firstmod.open_url&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test__fetch__happy_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://www.google.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# mock the return value of open_url&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;open_url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;Hello&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getcode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;open_url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stream&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Exercise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstmod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Verify&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;open_url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Line 1&lt;/strong&gt; - We patch an Ansible function which we expect &lt;code&gt;fetch()&lt;/code&gt; to call&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Line 4&lt;/strong&gt; - The url that we will pass on to &lt;code&gt;fetch()&lt;/code&gt;. We&amp;rsquo;re assigning it to
a variable here because we want to verify if it gets passed on to &lt;code&gt;open_url()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lines 7 to 10&lt;/strong&gt; - We mock the IO object that &lt;code&gt;open_url&lt;/code&gt; returns to &lt;code&gt;fetch()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lines 16 to 21&lt;/strong&gt; - We verify if &lt;code&gt;fetch()&lt;/code&gt; returned the correct data and that
it called the underlying &lt;code&gt;open_url()&lt;/code&gt; correctly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Run the test and see it fail. Let&amp;rsquo;s now write the code that makes it pass.
First, add this near the top of your &lt;code&gt;firstmod.py&lt;/code&gt; right after the first
import line:&lt;/p&gt;</description></item><item><title>Writing Ansible Modules Part 2 - Write Your First Module</title><link>https://relaxdiego.com/2016/09/writing-ansible-modules-002.html</link><pubDate>Wed, 28 Sep 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/09/writing-ansible-modules-002.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is part 2 of a series of articles. For other parts, see
&lt;a href="https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html"&gt;the introductory article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="its-just-somebodys-computer"&gt;It&amp;rsquo;s Just Somebody&amp;rsquo;s Computer&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s write a module for a fictitious cloud provider named Somebody&amp;rsquo;s Computer.
First, let&amp;rsquo;s create our module&amp;rsquo;s subdir:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir cloud/somebodyscomputer
$ touch cloud/somebodyscomputer/__init__.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From now on, I&amp;rsquo;ll refer to this as your &lt;strong&gt;module dir&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="lets-kick-the-tires-for-a-bit"&gt;Let&amp;rsquo;s Kick The Tires for a Bit&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s create a topic branch from the HEAD of devel and work there.
Working on a topic branch has its advantages in that, should new changes be
added to upstream/devel, all you have to do is fetch those and then rebase
your topic branch on top of it.&lt;/p&gt;</description></item><item><title>Writing Ansible Modules Part 1 - Preparing Your Environment</title><link>https://relaxdiego.com/2016/09/writing-ansible-modules-001.html</link><pubDate>Tue, 27 Sep 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/09/writing-ansible-modules-001.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;This is part 1 of a series of articles. For other parts, see
&lt;a href="https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html"&gt;the introductory article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ll need a few things handy before you can continue:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Git branching basics. &lt;a href="http://learngitbranching.js.org"&gt;Learn Git Branching&lt;/a&gt;
is a great resource!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Python &amp;gt;= 2.7.8 &amp;amp;&amp;amp; &amp;lt; 3.0.0. NOTE: Ansible works with Python 3.0+ and you
might be able to get the code samples in this article to work on it but I
haven&amp;rsquo;t tried it yet.&lt;/p&gt;</description></item><item><title>Writing Ansible Modules Complete With Tests</title><link>https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html</link><pubDate>Fri, 10 Jun 2016 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2016/06/writing-ansible-modules-with-tests.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/peshay"&gt;Andreas Hubert&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;While writing my first ansible module, I noticed that there wasn&amp;rsquo;t any resource
that completely described how to get started on my local dev environment.
This article documents the steps that I took to get up and running. Hopefully
it will be a helpful resource for you too.&lt;/p&gt;
&lt;p&gt;I should mention though that the following resources helped me get started
quickly in certain aspects. So a big thanks to the these folks! This article
builds on the foundations that they&amp;rsquo;ve started.&lt;/p&gt;</description></item><item><title>My Dev Setup (Part 3)</title><link>https://relaxdiego.com/2015/11/my-dev-setup-part-3.html</link><pubDate>Sat, 07 Nov 2015 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2015/11/my-dev-setup-part-3.html</guid><description>&lt;p&gt;It&amp;rsquo;s been over a year and a half since I posted about my development setup.
A lot has changed since then so I decided it was time to provide an update.
The most drastic change is that I&amp;rsquo;ve dropped TextMate, Sublime, and Atom and
finally took the plunge into the world of Vim and Tmux and, so far, I have
been very impressed with the results.&lt;/p&gt;
&lt;h1 id="swap-ctrl-and-caps-lock"&gt;Swap Ctrl and Caps Lock!&lt;/h1&gt;
&lt;p&gt;This is very important. Seriously. A lot of the commands and actions
that I mention below use Ctrl-A and Ctrl-(Vim movement keys).
Swapping my Ctrl and Caps Lock keys allows my fingers to stay in the
home row most of the time.&lt;/p&gt;</description></item><item><title>My First Attempt at Kubernetes</title><link>https://relaxdiego.com/2015/11/17-first-attempt-at-k8s.html</link><pubDate>Thu, 05 Nov 2015 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2015/11/17-first-attempt-at-k8s.html</guid><description>&lt;iframe width="560" height="315" src="https://www.youtube.com/embed/KP8TDdRThOc" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</description></item><item><title>Notes from CoreOS Fest 2015</title><link>https://relaxdiego.com/2015/05/coreosfest-notes.html</link><pubDate>Thu, 07 May 2015 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2015/05/coreosfest-notes.html</guid><description>&lt;p&gt;I went to the first CoreOS Fest this week and the following photo, of which I
am clearly the main subject, proves it!&lt;/p&gt;
&lt;center&gt;Source: &lt;a href="https://twitter.com/bradfitz/status/595726778422931456"&gt;@bradfitz on Twitter&lt;/a&gt;&lt;/center&gt;
&lt;img src="https://relaxdiego.com/assets/images/coreosfest2015.jpg" width="700" height="179"/&gt;
&lt;p&gt;Now that that&amp;rsquo;s out of the way, here are my notes from that event.&lt;/p&gt;
&lt;h2 id="container-all-the-things"&gt;Container all the things!&lt;/h2&gt;
&lt;p&gt;Oh yes, that reminds me. Before I talk about CoreOS Fest, let&amp;rsquo;s first establish
a common ground on this containerization thing. There appears to be some confusion
about what it is and whether it makes VMs obsolete (it does not).&lt;/p&gt;</description></item><item><title>Automated Testing, Organizational Learning, and Thermostats</title><link>https://relaxdiego.com/2015/01/automated-testing-and-organizational-learning.html</link><pubDate>Wed, 28 Jan 2015 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2015/01/automated-testing-and-organizational-learning.html</guid><description>&lt;p&gt;Agile software development is oftentimes touted as being a faster and more
efficient way of delivering software, as a way to reduce time to market, and as
a means to quickly respond to constantly changing requirements. That&amp;rsquo;s all well
and good until the message is misunderstood to mean &amp;ldquo;let&amp;rsquo;s skip documentation
and testing and just fix things as we go so that we can deliver within the
arbitrarily set deadline.&amp;rdquo; That&amp;rsquo;s not to say that Agile is no good. Rather, it&amp;rsquo;s
to point out that the need for software development speed must be tempered by
the need to retain organizational learning.&lt;/p&gt;</description></item><item><title>Using Aviator to Seed OpenStack</title><link>https://relaxdiego.com/2014/10/using-aviator-to-seed-openstack.html</link><pubDate>Thu, 02 Oct 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/10/using-aviator-to-seed-openstack.html</guid><description>&lt;p&gt;I added a change to Aviator so that you can use it to seed OpenStack. I had not thought
about this scenario when I built Aviator. The assumption from the get go was that it
will be used at that point in time when OpenStack has been installed and fully configured.
We were very lucky though that the changes needed to support this unexpected requirement were
very minimal. In fact, the changes were more syntactic sugar than anything else.
I&amp;rsquo;ll get to that part in a bit. First, let&amp;rsquo;s see how one might use Aviator to
seed OpenStack.&lt;/p&gt;</description></item><item><title>All About the OVSDB Server</title><link>https://relaxdiego.com/2014/09/ovsdb.html</link><pubDate>Sun, 21 Sep 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/09/ovsdb.html</guid><description>&lt;p&gt;In &lt;a href="https://relaxdiego.com/2014/09/hardware_vtep.html"&gt;my previous post&lt;/a&gt;, I briefly introduced
the OVSDB Management Protocol in the process of talking about hardware
VTEPs. In this post, I will focus on specific OVSDB Server features. And
to do that, I will (mis)use it outside of SDN.&lt;/p&gt;
&lt;h2 id="huh-but-ovsdb--sdn"&gt;Huh??? But OVSDB == SDN!&lt;/h2&gt;
&lt;p&gt;Actually, no. OVSDB can exist independent of Open vSwitch. In fact,
what&amp;rsquo;s actually happening under the covers is that Open vSwitch connects
to OVSDB and monitors certain tables in the Open_vSwitch database for
updates. When OVS receives update notifications from OVSDB, the former
then gets to work creating and manipulating bridges, ports, etc.&lt;/p&gt;</description></item><item><title>Understanding Hardware VTEPs</title><link>https://relaxdiego.com/2014/09/hardware_vtep.html</link><pubDate>Tue, 09 Sep 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/09/hardware_vtep.html</guid><description>&lt;p&gt;In &lt;a href="https://relaxdiego.com/2014/09/ovs-lab.html"&gt;my previous post&lt;/a&gt;, I announced that I open sourced
my Open vSwitch lab as well as the scripts and files that I produced as I
followed David Mahler&amp;rsquo;s &lt;a href="https://www.youtube.com/watch?v=tnSkHhsLqpM"&gt;introduction to VXLAN overlay networks with Open
vSwitch&lt;/a&gt;. In this post, I&amp;rsquo;m going
to re-purpose my Open vSwitch lab to explore hardware VXLAN tunnel endpoints
(HW VTEP).&lt;/p&gt;
&lt;h2 id="a-quick-review-of-hardware-vteps"&gt;A Quick Review of Hardware VTEPs&lt;/h2&gt;
&lt;p&gt;The idea behind hardware VTEPs is to create an overlay network that connects VMs
and Physical Servers and make them think that they&amp;rsquo;re in the same L2 network
even if they&amp;rsquo;re on opposite sides of the globe.&lt;/p&gt;</description></item><item><title>Your Own Open vSwitch Lab</title><link>https://relaxdiego.com/2014/09/ovs-lab.html</link><pubDate>Wed, 03 Sep 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/09/ovs-lab.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been spending a lot of time studying Open vSwitch and VXLAN lately and,
often, found the need to quickly destroy and recreate my OVS environment. To speed
up that process, I created my own Vagrant project which I&amp;rsquo;ve just made available
on my Github account. You may find it &lt;a href="https://github.com/relaxdiego/ovs-lab"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With a simple &lt;code&gt;vagrant up&lt;/code&gt; command, you will be able to spin up two host machines
that talk to each other over a simulated Internet (which is implemented as another
VM). Each host machine comes with OVS 2.x and &lt;a href="http://mininet.org/"&gt;Mininet&lt;/a&gt;
so that you can spin up a handful of guest machines without consuming too much
resources. Each host machine consumes only 256 MB of RAM but can be increased
via the Vagrantfile in the project&amp;rsquo;s root directory.&lt;/p&gt;</description></item><item><title>Aviator now supports Keystone V3 authentication</title><link>https://relaxdiego.com/2014/07/aviator-keystone-v3.html</link><pubDate>Sun, 13 Jul 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/07/aviator-keystone-v3.html</guid><description>&lt;p&gt;I just recently merged a &lt;a href="https://github.com/aviator/aviator/pull/104"&gt;significant change&lt;/a&gt;
to the master branch. This change now allows for authenticating against Keystone&amp;rsquo;s V3 API.
That means that, as of right now, running the &lt;a href="https://github.com/aviator/demo/blob/master/demo/create_server.rb"&gt;create server&lt;/a&gt;
demo using the following config file works as expected (must use bleeding-edge Aviator
from &lt;a href="https://github.com/aviator/aviator/tree/master"&gt;HEAD of master&lt;/a&gt;).&lt;/p&gt;
&lt;script src="https://gist.github.com/relaxdiego/324042ce68aa1065118f.js"&gt;&lt;/script&gt;
&lt;h2 id="override-api-version-to-use"&gt;Override API version to use&lt;/h2&gt;
&lt;p&gt;You may have noticed that extra section at the bottom of the sample
config file above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;compute_service:
 api_version: v2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That setting allows you to override Aviator&amp;rsquo;s behavior and make sure that
you always use Nova&amp;rsquo;s v2 API, even if API V3 is available alongside V2. In
fact, if more than one API version is available for a service, you will
need to specify which one you want to choose in the configuration file.&lt;/p&gt;</description></item><item><title>Hiding Sensitive Data from Logs with Python</title><link>https://relaxdiego.com/2014/07/logging-in-python.html</link><pubDate>Sat, 05 Jul 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/07/logging-in-python.html</guid><description>&lt;p&gt;&lt;sup&gt;Co-Written by &lt;a href="https://github.com/haridsv"&gt;Hari Dara&lt;/a&gt; and &lt;a href="https://github.com/uenz"&gt;uenz&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Last week I&amp;rsquo;ve had to wrangle with Python&amp;rsquo;s documentation because I needed one
of the apps I&amp;rsquo;m writing to centrally remove sensitive information from the logs. After
several attempts at understanding the documentation, I&amp;rsquo;ve come to appreciate
the built-in logging framework. I also have to admit that it&amp;rsquo;s more powerful
than Ruby&amp;rsquo;s built in logger.&lt;/p&gt;
&lt;p&gt;There are definitely more than one approach to solve this problem, but I will discuss a couple of approaches below:&lt;/p&gt;</description></item><item><title>Hardware VTEP and OVSDB</title><link>https://relaxdiego.com/2014/06/hardware-vtep-and-ovsdb.html</link><pubDate>Fri, 27 Jun 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/06/hardware-vtep-and-ovsdb.html</guid><description>&lt;p&gt;Here are some of my rough notes on OVSDB and hardware VTEP.&lt;/p&gt;
&lt;h2 id="the-rise-of-virtual-networks"&gt;The Rise of Virtual Networks&lt;/h2&gt;
&lt;p&gt;With the advent of Software Defined Networking (SDN), new networking capabilities are opened up to an organization. Just imagine being able to programmatically request from your provider a two-fold increase in your bandwidth between 10 AM and 12 AM today when you will need to send a bulk of data offsite and then paying only extra for that increase within that time. It&amp;rsquo;s an exciting time for networking as it finally completes the utility-based computing we&amp;rsquo;ve been talking about for years now. Granted we can&amp;rsquo;t do that quick bandwidth burst as of today, but we&amp;rsquo;re getting there.&lt;/p&gt;</description></item><item><title>Analyzing Team Performance Using Trello Data</title><link>https://relaxdiego.com/2014/04/analyzing-performance-using-trello-data.html</link><pubDate>Sat, 12 Apr 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/04/analyzing-performance-using-trello-data.html</guid><description>&lt;p&gt;&lt;strong&gt;UPDATE 2014-04-24:&lt;/strong&gt; Code related to this post is now available in &lt;a href="https://github.com/NexusIS/rosetta"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve been using Trello exclusively at my new job for managing our tasks.
As an outsider, I&amp;rsquo;d say that the Trello team did a very good job
of identifying the application&amp;rsquo;s core features and relentlessly
focusing on those. One of the features that I appreciate is how it
made creating and updating cards so easy and fast. As an agile developer
for over 5 years now, I&amp;rsquo;ve found that the lack of this feature is invariably
one of the things that stand in the way of a team fully adopting agile
practices. That&amp;rsquo;s also what led me to write &lt;a href="http://www.redminebacklogs.net"&gt;Redmine Backlogs&lt;/a&gt;
back in 2008.&lt;/p&gt;</description></item><item><title>Mocking Objects in Python</title><link>https://relaxdiego.com/2014/04/mocking-objects-in-python.html</link><pubDate>Mon, 07 Apr 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/04/mocking-objects-in-python.html</guid><description>&lt;p&gt;Mocking in Python can be initially confusing and &lt;a href="https://docs.python.org/3/library/unittest.mock.html"&gt;the official docs&lt;/a&gt;,
while informative, don&amp;rsquo;t make learning it any easier for newcomers. In my case,
I came across it when I was still transitioning from Ruby which, I believe,
contributed to the confusion. This article takes a gentler approach to learning
Python&amp;rsquo;s mocking library to help you get productive sooner.&lt;/p&gt;
&lt;h2 id="importing-objects-a-review"&gt;Importing Objects: A Review&lt;/h2&gt;
&lt;p&gt;The &lt;a href="https://docs.python.org/3/library/unittest.mock.html"&gt;unittest.mock&lt;/a&gt; library builds
on top of how Python implements &lt;a href="https://docs.python.org/3/reference/import.html"&gt;the import statement&lt;/a&gt;
so it&amp;rsquo;s imperative that we have a solid understanding of how it works before we can continue.&lt;/p&gt;</description></item><item><title>My Development Setup (Python Edition)</title><link>https://relaxdiego.com/2014/03/my-dev-setup-python-edition.html</link><pubDate>Sun, 09 Mar 2014 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2014/03/my-dev-setup-python-edition.html</guid><description>&lt;p&gt;Now that my work includes coding in Python, the first thing that I paid
attention to was all the Python tools that allowed me to replicate &lt;a href="https://relaxdiego.com/2013/06/my-dev-setup.html"&gt;my dev
setup in Ruby&lt;/a&gt;. Here&amp;rsquo;s what I have so far.&lt;/p&gt;
&lt;h2 id="tdd"&gt;TDD&lt;/h2&gt;
&lt;p&gt;Testing to me these days is a lot like seatbelts while riding a car. I do not
feel safe without them. So mastering a testing framework is always top priority for me when diving into a new language. I tried &lt;a href="https://nose.readthedocs.org/en/latest/"&gt;nose&lt;/a&gt; but it appears to have lost favor
from &lt;a href="http://openstacksummitfall2012.sched.org/event/524523c3c35a299ce12236cc4ccdc8e6#.Ux0NnuddXQ8"&gt;one of the open-source communities I&amp;rsquo;m in&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>I Love Elegant Solutions</title><link>https://relaxdiego.com/2013/09/i-love-elegant-solutions.html</link><pubDate>Sun, 15 Sep 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/09/i-love-elegant-solutions.html</guid><description>&lt;p&gt;Last week while I was playing around with ManaMana&amp;rsquo;s self-testing capability, I came across a problem where I needed the RDSL syntax to allow for preformatted blocks in requirements such as the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;* A Wiki page displays the following text
 ```
 Dear World,
 Hello!
 ```
 when it is newly generated.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Modifying the RDSL lexer to recognize the preformatted blocks was the easy part. The problem after that was how do I strip whitespace in the requirements while preserving it inside the preformatted blocks? Initially, I thought about the following process:&lt;/p&gt;</description></item><item><title>Testing ManaMana with ManaMana</title><link>https://relaxdiego.com/2013/09/testing-manamana-with-manamana.html</link><pubDate>Fri, 13 Sep 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/09/testing-manamana-with-manamana.html</guid><description>&lt;p&gt;Last night at the &lt;a href="http://www.meetup.com/laruby/events/129338842/"&gt;September LA Ruby Meetup&lt;/a&gt;, I got the chance to present &lt;a href="https://github.com/ManaManaFramework/manamana"&gt;ManaMana&lt;/a&gt;, my BDD framework hobby project, and the tools I used to build it. At one point during the presentation, Michael Hartl (author of &lt;a href="http://ruby.railstutorial.org/"&gt;Rails Tutorial&lt;/a&gt;), asked if ManaMana can test itself. It didn&amp;rsquo;t at that time.&lt;/p&gt;
&lt;p&gt;Obviously, the idea of a self-testing ManaMana gnawed on me for the rest of the night. So earlier today, I decided to give it a go. Now, I have &lt;a href="https://gist.github.com/relaxdiego/6557728"&gt;these files&lt;/a&gt; in the project and when I run &lt;code&gt;bundle exec guard&lt;/code&gt; from the command line and save the requirement or test case files above, ManaMana compiles the test and produces &lt;a href="https://gist.github.com/relaxdiego/6557806"&gt;the following output&lt;/a&gt;. So yeah, we now have a self-testing test framework with ManaMana.&lt;/p&gt;</description></item><item><title>Mocking Web Services with VCR</title><link>https://relaxdiego.com/2013/06/mocking-web-services-with-vcr.html</link><pubDate>Sat, 22 Jun 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/06/mocking-web-services-with-vcr.html</guid><description>&lt;p&gt;When writing applications or libraries on top of 3rd party web services, one often encounters connectivity problems ranging from slow to zero connection. Then there&amp;rsquo;s the issue of rate limits where your machine can only make X number of requests per day. Any one of these issues is a killer on developer flow. Thankfully, numerous open-source tools abound that let you create a mock of a 3rd-party web service&amp;rsquo;s API.&lt;/p&gt;</description></item><item><title>My Development Setup</title><link>https://relaxdiego.com/2013/06/my-dev-setup.html</link><pubDate>Fri, 07 Jun 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/06/my-dev-setup.html</guid><description>&lt;p&gt;The open source software movement has come a long way and I&amp;rsquo;m particularly excited by the improvements
made in automated code QA and how it empowers a small team (sometimes, a team of one)
to develop software that, just a few years ago, required a large group of programmers and testers
and long development times mostly comprising of manual code reviews.&lt;/p&gt;
&lt;p&gt;How does automated code QA make this happen, you ask? Let me explain by walking you through
my local development setup of my latest two open source projects, the &lt;a href="https://github.com/ManaManaFramework/manamana"&gt;ManaMana Framework&lt;/a&gt;, and &lt;a href="https://github.com/relaxdiego/redstack/tree/develop"&gt;RedStack&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Fun with iperf</title><link>https://relaxdiego.com/2013/05/iperf.html</link><pubDate>Fri, 10 May 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/05/iperf.html</guid><description>&lt;p&gt;Casual bandwidth testing is easy enough to measure. Just &lt;code&gt;wget&lt;/code&gt; a large file from some source on the Internet and you&amp;rsquo;ll get your results. For more precise measurements, however, this will not do. Some examples of when &lt;code&gt;wget&lt;/code&gt; is insufficient are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You need to measure a machine&amp;rsquo;s download speed in relation to another machine in the network irrespective of the latter machine&amp;rsquo;s configuration/hardware (e.g. Apache config, disk speed)&lt;/li&gt;
&lt;li&gt;You need to measure a machine&amp;rsquo;s upload speed in relation to another machine in the network.&lt;/li&gt;
&lt;li&gt;You need to measure DL or UL rate for UDP&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In these and other cases requiring precise measurement, &lt;code&gt;iperf&lt;/code&gt; does the job very well. In my case, I needed to test a physical machine&amp;rsquo;s ability to throttle the bandwidth of the VMs it hosts. So our set up was to use iperf between a VM in the machine and another host in the network (not a VM in the physical machine, and not the physical machine).&lt;/p&gt;</description></item><item><title>Adventures With Norm</title><link>https://relaxdiego.com/2013/02/adventures-with-norm.html</link><pubDate>Tue, 26 Feb 2013 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2013/02/adventures-with-norm.html</guid><description>&lt;p&gt;It&amp;rsquo;s been &lt;a href="https://relaxdiego.com/2012/04/using-cucumber.html"&gt;almost&lt;/a&gt; &lt;a href="https://relaxdiego.com/2012/04/on-cucumbers-opinionatedness.html"&gt;a&lt;/a&gt; &lt;a href="https://relaxdiego.com/2012/05/how-we-use-cucumber-the-sequel.html"&gt;year&lt;/a&gt; since I dived more deeply into automated requirements verification/QA while attempting to apply my new knowledge through a number of &lt;a href="https://github.com/norm-framework"&gt;Norm prototypes&lt;/a&gt;. It&amp;rsquo;s been slow going, but very interesting thanks to a plethora of useful resources including &lt;a href="http://www.satisfice.com/articles.shtml"&gt;James Bach&amp;rsquo;s site&lt;/a&gt; and &lt;a href="http://createyourproglang.com/"&gt;This Freaking Awesome Book&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My biggest takeaway from this so far is that it&amp;rsquo;s just not feasible to automate the verification of each and every requirement. No doubt it&amp;rsquo;s possible, but there will be times when the benefits are overshadowed by the costs of automation. There are various reasons why this is so. Sometimes it&amp;rsquo;s because there are some discrepancies that are hard to describe in writing, but you know it when you see it. In other times, it may be because you just don&amp;rsquo;t know what the output will look like (e.g. a chart that displays some non-deterministic trend). There are many other reasons but that&amp;rsquo;s not to say that automation has absolutely no place in those examples. For instance, we could automated the setup and teardown steps of a test case while leaving the body of said test case (or even just the verification step) to the human. And so this is what gave me new ideas that I might add to my next prototype:&lt;/p&gt;</description></item><item><title>Writing a Compiler (Part 1)</title><link>https://relaxdiego.com/2012/07/writing-a-compiler-1.html</link><pubDate>Thu, 26 Jul 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/07/writing-a-compiler-1.html</guid><description>&lt;p&gt;This is the first in a series of posts where I will talk about how I wrote compilers for two languages that I designed. These languages, namely &amp;ldquo;BA Speak&amp;rdquo; and &amp;ldquo;QA Speak&amp;rdquo;, are external domain-specific languages (DSL). They are DSLs because they have a very specific usage and are not general purpose languages. They are external because they are not constrained by the syntax rules of a host language.&lt;/p&gt;
&lt;h2 id="about-ba-speak-and-qa-speak"&gt;About BA Speak and QA Speak&lt;/h2&gt;
&lt;p&gt;BA Speak and QA Speak are DSLs that I created for a prototype framework I call Norm Framework. You can see the various prototypes of this framework &lt;a href="https://github.com/norm-framework"&gt;here&lt;/a&gt;. Norm was inspired by &lt;a href="http://cukes.info"&gt;Cucumber&lt;/a&gt; and the &lt;a href="http://code.google.com/p/robotframework/"&gt;Robot Framework&lt;/a&gt; which are automated acceptance test frameworks used for verifying a piece of software against a set of specifications.&lt;/p&gt;</description></item><item><title>First impression of Python</title><link>https://relaxdiego.com/2012/06/first-impression-of-python.html</link><pubDate>Thu, 28 Jun 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/06/first-impression-of-python.html</guid><description>&lt;p&gt;I&amp;rsquo;ve started learning about Python during my free time and one of the things
that bothers me is the fact that I have to use the len() function on an object
instead of just calling a length method on that object. I&amp;rsquo;ve read the
discussions online about this (e.g. &lt;a href="http://effbot.org/pyfaq/why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list.htm"&gt;1&lt;/a&gt;,
&lt;a href="http://stackoverflow.com/questions/237128/is-there-a-reason-python-strings-dont-have-a-string-length-method"&gt;2&lt;/a&gt;, &lt;a href="http://lucumr.pocoo.org/2011/7/9/python-and-pola/"&gt;3&lt;/a&gt;) and my attempt
to summarize the justifications are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;len() has better clarity of intent&lt;/li&gt;
&lt;li&gt;&amp;rsquo;length&amp;rsquo; has a different meaning for different objects&lt;/li&gt;
&lt;li&gt;That&amp;rsquo;s how it&amp;rsquo;s always been from the beginning&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m not convinced at all by reason #1. Compare the following:&lt;/p&gt;</description></item><item><title>How We Use Cucumber, The Sequel</title><link>https://relaxdiego.com/2012/05/how-we-use-cucumber-the-sequel.html</link><pubDate>Thu, 24 May 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/05/how-we-use-cucumber-the-sequel.html</guid><description>&lt;p&gt;In a &lt;a href="https://relaxdiego.com/2012/04/using-cucumber.html"&gt;previous post&lt;/a&gt;, I explained how we used Cucumber. Now, after about a month of using the recommended style, we&amp;rsquo;ve noticed some &amp;lsquo;usability problems&amp;rsquo; and introduced our own styles.&lt;/p&gt;
&lt;h3 id="readability-of-stepdefs"&gt;Readability of stepdefs&lt;/h3&gt;
&lt;p&gt;The following is how our steps used to be defined:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Then /^I can disable notifications$/i do
 Notifier.fill_in 'username', 'jdoe'
 Notifier.fill_in 'password', '123qwe'
 Notifier.click 'login'
 Notifier.click 'disable'

 Notifier.should_be_disabled
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&amp;rsquo;s nice, clean, and readable&amp;hellip;for a programmer. However, stepdefs are not exclusive to programmers: testers also need to be able to review them to know if the test is thorough or accurate. We have smart testers who know how to find edge cases or break an application, but they don&amp;rsquo;t know how to code. Things like dot notation and remembering to enclose a string with quotations are alien to them. They already understand English though and since we found that it&amp;rsquo;s easy to modify the above code to read like English, we thought it would be better to write stepdefs that the Testers can use within stepdefs. One example of such a stepdef is:&lt;/p&gt;</description></item><item><title>On Cucumber's Opinionatedness</title><link>https://relaxdiego.com/2012/04/on-cucumbers-opinionatedness.html</link><pubDate>Sat, 21 Apr 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/04/on-cucumbers-opinionatedness.html</guid><description>&lt;p&gt;In &lt;a href="https://relaxdiego.com/2012/04/using-cucumber.html"&gt;a previous post&lt;/a&gt;, I said that Cucumber&amp;rsquo;s flexibility is both a boon and a curse to teams who are just getting to know it. I said this because it&amp;rsquo;s so easy to get started with the Gherkin syntax that users get a little too excited and start to tinker with it in their own way which doesn&amp;rsquo;t always produce the right results. It&amp;rsquo;s just like a game of Othello: very easy to learn, but hard to master. One has to understand the principles behind it to win.&lt;/p&gt;</description></item><item><title>How We Use Cucumber</title><link>https://relaxdiego.com/2012/04/using-cucumber.html</link><pubDate>Thu, 19 Apr 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/04/using-cucumber.html</guid><description>&lt;p&gt;Lately I&amp;rsquo;ve been very involved in the conversion of our product requirements and
test scripts into executable documentation via Cucumber. We initially ran
into problems with deciding what goes into the feature files and what goes
into the step definitions. More than once we have had to stop and ask ourselves
if the feature files are too imperative or too high level. There was a lot of
back and forth until we settled on the following style.&lt;/p&gt;</description></item><item><title>We've Moved</title><link>https://relaxdiego.com/2012/03/weve-moved.html</link><pubDate>Tue, 13 Mar 2012 00:00:00 +0000</pubDate><guid>https://relaxdiego.com/2012/03/weve-moved.html</guid><description>&lt;p&gt;This site is now powered by &lt;a href="http://pages.github.com/"&gt;Github Pages&lt;/a&gt; and &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>All about the ECU</title><link>https://relaxdiego.com/2012/02/all-about-the-ecu.html</link><pubDate>Wed, 29 Feb 2012 17:56:00 +0000</pubDate><guid>https://relaxdiego.com/2012/02/all-about-the-ecu.html</guid><description>&lt;h3 id="what-is-an-ecu"&gt;What is an ECU?&lt;/h3&gt;
&lt;p&gt;ECU means &amp;ldquo;EC2 Compute Unit&amp;rdquo;&lt;/p&gt;
&lt;h3 id="ok-but-what-does-it-stand-for"&gt;OK, but what does it stand for?&lt;/h3&gt;
&lt;p&gt;First, let me explain what a VM is. A VM is defined by its:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Processing power&lt;/li&gt;
&lt;li&gt;RAM, and&lt;/li&gt;
&lt;li&gt;Local storage&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="what-about-ecu"&gt;What about ECU?&lt;/h3&gt;
&lt;p&gt;Well, an ECU is just a unit of measurement for a VM&amp;rsquo;s processing power and has nothing to do with RAM, or storage.&lt;/p&gt;
&lt;h3 id="cool-but-what-does-an-ecu-really-mean"&gt;Cool, but what does an ECU really mean??&lt;/h3&gt;
&lt;p&gt;OK, have a seat.&lt;/p&gt;</description></item><item><title>Using GCC when Xcode 4.2 or 4.3 is installed</title><link>https://relaxdiego.com/2012/02/using-gcc-when-xcode-43-is-installed.html</link><pubDate>Wed, 22 Feb 2012 10:35:00 +0000</pubDate><guid>https://relaxdiego.com/2012/02/using-gcc-when-xcode-43-is-installed.html</guid><description>&lt;p&gt;I was having problems compiling gems from the terminal in my Mac last week.
After further investigation and some Googling, I found out that it was because
Xcode 4.3 now uses the LLVM-based gcc and not all native gems support it. I
then installed the &lt;a href="https://developer.apple.com/downloads/index.action"&gt;Command Line Tools for
Xcode&lt;/a&gt; hoping that would
solve the problem. Unfortunately, it didn&amp;rsquo;t. At least not completely.&lt;/p&gt;
&lt;p&gt;After some more digging around, I came to realize that &lt;code&gt;/usr/bin/gcc&lt;/code&gt;, which
is what gets used by default, is actually symlinked to
&lt;code&gt;/usr/bin/llvm-gcc-4.2&lt;/code&gt;. I tried setting &lt;code&gt;CC=/usr/bin/gcc-4.2&lt;/code&gt; whenever I
installed gems, but somehow that gets lost along the way. Some suggested that
I downgrade to Xcode 4.1 or even uninstall Xcode altogether. However, in my
case, I use Xcode every now and then so that was not an option.&lt;/p&gt;</description></item><item><title>Trouble accessing Google from the Philippines?</title><link>https://relaxdiego.com/2012/02/trouble-accessing-google-from-the-philippines.html</link><pubDate>Thu, 16 Feb 2012 12:33:00 +0000</pubDate><guid>https://relaxdiego.com/2012/02/trouble-accessing-google-from-the-philippines.html</guid><description>&lt;p&gt;I&amp;rsquo;m using Globe Tattoo Home DSL and I&amp;rsquo;ve had to deal with this problem for a
number of days and tried different solutions to no avail, until an officemate
of mine suggested that it might be a DNS peering problem between Globe and
Google. He then told me to set my primary and secondary DNS to 4.2.2.2 and
4.2.2.1 respectively and voila!&lt;/p&gt;
&lt;p&gt;As another officemate once said about Internet connectivity issues: it&amp;rsquo;s
always a DNS problem.&lt;/p&gt;</description></item><item><title>Objective C</title><link>https://relaxdiego.com/2011/12/objective-c.html</link><pubDate>Thu, 29 Dec 2011 11:03:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/objective-c.html</guid><description>&lt;p&gt;Objective-C implements weak typing, blocks (aka anonymous functions or
closures), key-value coding (aka accessing an object&amp;rsquo;s methods and properties
as if the object was a dictionary), monkeypatching, etc. It&amp;rsquo;s a dynamic
language with the power of C. It&amp;rsquo;s Ruby and Python&amp;rsquo;s uglier but more efficient
sister. It has its own quirks that might put you off at the start, but the
more I learn about it, the more I like it.&lt;/p&gt;</description></item><item><title>Jogging Without Gadgets</title><link>https://relaxdiego.com/2011/12/jogging-without-gadgets.html</link><pubDate>Thu, 22 Dec 2011 02:00:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/jogging-without-gadgets.html</guid><description>&lt;p&gt;When I go out for my regular 10~12k jog, I don&amp;rsquo;t bring any mp3 player with me.
In fact, I don&amp;rsquo;t carry any gadgets at all: the only items on me are my
sleeveless shirt, jogging shorts, and running shoes. It wasn&amp;rsquo;t always this
way. When I started out, I would fill my iPod to the brim with supposedly
energizing music. But after a while, the music started to get old, so I&amp;rsquo;d find
more music to replace the old ones. Repeat ad nauseum.&lt;/p&gt;</description></item><item><title>Theory of Constraints: Drum-Buffer-Rope</title><link>https://relaxdiego.com/2011/12/theory-of-constraints-drum-buffer-rope.html</link><pubDate>Mon, 12 Dec 2011 08:19:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/theory-of-constraints-drum-buffer-rope.html</guid><description>&lt;p&gt;&lt;em&gt;This is an old report I wrote back in 2005 as a result of simulating
different ways to streamline the process in the machine fabrication shop I
worked for back then.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Traditionally, the scheduling method used in a small manufacturing shop (let&amp;rsquo;s
call it MMS) has been more of guesswork wherein job orders are issued as they
come. The main problem with this scenario is that as more job orders enter the
shop floor, the larger the work-in-progress (WIP) inventory gets. As a result,
idle times for job orders will severely fluctuate contributing to the
variability of delivery times for job orders. The bottom line is that
supervisors and sales representatives will not have enough data (and
confidence) to come up with an accurate completion time estimate for every job
order. Often times, they will resort to padding up the completion dates and/or
compromising less critical jobs just to avoid late deliveries.&lt;/p&gt;</description></item><item><title>Elegant Solutions</title><link>https://relaxdiego.com/2011/12/elegant-solutions.html</link><pubDate>Tue, 06 Dec 2011 05:58:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/elegant-solutions.html</guid><description>&lt;p&gt;I like elegant solutions because they are easier to administer. In fact, I
believe that a solution is truly elegant if you do not even need to actively
administer it. One thing to note about elegance though is that it&amp;rsquo;s hard to
achieve if you&amp;rsquo;re harried, if you&amp;rsquo;re out of time, trying to deal with too many
things at time, etc. So it&amp;rsquo;s important to be aware of you current state of
mind and be sure that you are focused. Otherwise, you&amp;rsquo;ll never achieve that
elegant solution you have in mind.&lt;/p&gt;</description></item><item><title>Explaining Cloud Computing</title><link>https://relaxdiego.com/2011/12/explaining-cloud-computing.html</link><pubDate>Sat, 03 Dec 2011 03:46:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/explaining-cloud-computing.html</guid><description>&lt;p&gt;Cloud computing is a hot topic these days and while nearly every IT
professional knows what it is, the rest of the world is still unsure about it.
In my current job, part of my responsibilities is to explain this concept in
the simplest terms especially for non-technical people and I do this by saying
that cloud computing simply changes how we acquire computers or software. The
following two slides are usually part of my arsenal:&lt;/p&gt;</description></item><item><title>Rails, Sinatra, or Express (for Node)? Decisions, decisions.</title><link>https://relaxdiego.com/2011/12/rails-sinatra-or-express-for-node-decisions-decisions.html</link><pubDate>Thu, 01 Dec 2011 12:32:00 +0000</pubDate><guid>https://relaxdiego.com/2011/12/rails-sinatra-or-express-for-node-decisions-decisions.html</guid><description>&lt;p&gt;I&amp;rsquo;ve been evaluating these three frameworks yesterday and while I have to say
that the speed of Express is really going to be critical in the long run, I
think it&amp;rsquo;s premature to use it at this point in time. What I need to do right
now is get a prototype up and running quickly so as to keep myself motivated.
Sinatra is really the same as Express (albeit a little slower and less of the
asynchronous goodness) so I&amp;rsquo;ll have to avoid using it at this time.&lt;/p&gt;</description></item><item><title>Things That Are Smaller Than Apple, Inc.</title><link>https://relaxdiego.com/2011/11/things-that-are-smaller-than-apple-Inc.html</link><pubDate>Thu, 24 Nov 2011 09:28:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/things-that-are-smaller-than-apple-Inc.html</guid><description>&lt;p&gt;This may not be a slideshow, but it certainly is a good example of how to
present numbers. Notice how this infographic does away with fancy graphics and
yet gets the point across. I&amp;rsquo;d recommend using this for any comparison data.
Chart purists might have a beef with the fact that it uses areas instead of
the more technically accurate bar charts, but I  think that it&amp;rsquo;s really
effective in getting the point across.&lt;/p&gt;</description></item><item><title>Drupal, WordPress, Joomla!</title><link>https://relaxdiego.com/2011/11/drupal-wordPress-joomla.html</link><pubDate>Mon, 21 Nov 2011 21:25:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/drupal-wordPress-joomla.html</guid><description>&lt;p&gt;Today I will pick a slide that I like and suggest improvements to it.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-wordpressdrupaljoomla.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-wordpressdrupaljoomla.png" alt="" width="320" height="238" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I like the whimsical chart even though it&amp;rsquo;s not technically accurate because
it sends the message across very clearly. Just one thing I&amp;rsquo;d change there is
to move the CMS names from the legend at the bottom to immediately to the
right of each plot. There&amp;rsquo;s also more than enough whitespace in this slide
that could&amp;rsquo;ve been used to make the chart easier to read.&lt;/p&gt;</description></item><item><title>Redmine Dashboard</title><link>https://relaxdiego.com/2011/11/redmine-dashboard.html</link><pubDate>Sun, 20 Nov 2011 10:22:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/redmine-dashboard.html</guid><description>&lt;p&gt;A little something I wrote while I was on a plane from Manila to LA a few
months back. This is actually the earliest prototype of the mini-project I was
talking about earlier. I used
&lt;a href="http://documentcloud.github.com/backbone/"&gt;backbone.js&lt;/a&gt; and I really feel
that it helped me speed up development. It took a little time to get my head
wrapped around the collection concept but once I understood that, everything
else made a lot of sense. Here&amp;rsquo;s a screenshot of how it looks like once you
get it working:&lt;/p&gt;</description></item><item><title>Acromag</title><link>https://relaxdiego.com/2011/11/acromag.html</link><pubDate>Fri, 18 Nov 2011 21:23:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/acromag.html</guid><description>&lt;p&gt;If you have to show a diagram or a workflow, always make sure the audience
knows where to start looking and where to look next. This slide was very
confusing and even had a number of elements that didn&amp;rsquo;t help explain what was
going on.&lt;/p&gt;
&lt;p&gt;Original Slide&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-acromag.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-acromag.png" alt="" width="320" height="238" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My Rendition&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-acromag.001.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-acromag.001.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Some notes: Apart from the fact that I have no idea where the process starts
and ends from looking at the slide above, I also have no idea about monitoring
diesel engines. So I didn&amp;rsquo;t bother fully replicating the information in my
rendition. Key takeaways here though are:&lt;/p&gt;</description></item><item><title>A Buyer's Guide to Storage Virtualization</title><link>https://relaxdiego.com/2011/11/a-buyers-guide-to-storage-virtualization.html</link><pubDate>Thu, 17 Nov 2011 21:21:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/a-buyers-guide-to-storage-virtualization.html</guid><description>&lt;p&gt;Bulletpoints can be useful sometimes, but great care must be taken when using
them. You don&amp;rsquo;t want your slides to replace you, the speaker. Even worse is if
you use your bullets as speaker notes. Use an index card for crying out
loud!&lt;/p&gt;
&lt;p&gt;Original Slide&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-buyers_guide.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-buyers_guide.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My Rendition&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-buyers_guide.001.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-buyers_guide.001.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t hide behind bulletpoints. Make the audience focus on you and what you
have to say. Practice your speech and clean it up so that you only have to say
the most important things. Afterwards, share with them some takeaway notes
that they can read on their own time.&lt;/p&gt;</description></item><item><title>FAQ generator</title><link>https://relaxdiego.com/2011/11/faq-generator.html</link><pubDate>Thu, 17 Nov 2011 09:30:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/faq-generator.html</guid><description>&lt;p&gt;Here&amp;rsquo;s a quick and dirty ruby script I made to extract issues from a project
in Redmine and output it to an HTML file. I originally wrote this to compile
issues in a project named &amp;lsquo;FAQs&amp;rsquo; where we internally discuss FAQs and their
answers before publishing to the wild. Check it out at
&lt;a href="https://github.com/relaxdiego/FAQs"&gt;Github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After looking at that code, you might ask why I used pandoc instead of plain
old erb or some other Ruby-based templating gem. The reason is that I
originally started out by outputting a PDF file but then requirements changed
and I had to come up with something very quickly. Needless to say, my fingers
are itching to clean up this code. Soon&amp;hellip;&lt;/p&gt;</description></item><item><title>Radisys</title><link>https://relaxdiego.com/2011/11/radisys.html</link><pubDate>Tue, 15 Nov 2011 21:17:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/radisys.html</guid><description>&lt;p&gt;This slide was presenting too much information at once so I broke it down into
3 different slides to highlight 3 very important things for the audience.&lt;/p&gt;
&lt;p&gt;Original Slide&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-radisys.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-radisys.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; My Rendition (Broken down to 3 slides)&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-radisys.001.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-radisys.001.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-radisys.002.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-radisys.002.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-radisys.003.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-radisys.003.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Original slides are
&lt;a href="http://www.slideshare.net/Radisys/4-g-world-unraveling4gran"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>HDS Cloud Strategy</title><link>https://relaxdiego.com/2011/11/hds-cloud-strategy.html</link><pubDate>Wed, 09 Nov 2011 21:09:00 +0000</pubDate><guid>https://relaxdiego.com/2011/11/hds-cloud-strategy.html</guid><description>&lt;p&gt;3D charts, really, are unecessary: it distorts the visual information making
side by side comparison difficult. To make matters worse, the “3D-fication” of
the bar chart changes one of the data points below such that its color doesn&amp;rsquo;t
match what&amp;rsquo;s in the legend.&lt;/p&gt;
&lt;p&gt;Original Slide&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-storage_vision_2011.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-storage_vision_2011.png" alt="" width="320" height="239" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My Rendition&lt;/p&gt;
&lt;p&gt;&lt;a href="https://relaxdiego.com/assets/images/blogger/s1600-storage_vision_2011.001.png"&gt;&lt;img src="https://relaxdiego.com/assets/images/blogger/s320-storage_vision_2011.001.png" alt="" width="320" height="240" loading="lazy" decoding="async"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Original slides are
&lt;a href="http://www.slideshare.net/hdscorp/td2011-s-vpresentation"&gt;here&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>