Thursday, August 1, 2013

Working from Home

Since I've radically changed my work VM configuration, I needed to change my home PC in order to connect properly to the new setup.

Before we dive in, a brief review of the old setup: the host at work, which we will call `audia`, ran a VirtualBox guest named `dev`.  dev had its own set of configs and configuration knobs so that I could write 127.0.0.1 dev.audia.pc dev into /etc/hosts, point Firefox to dev:10080, and code running on dev would be able to recognize "this is development," not require TLS, and know that http://dev:10080/ is the URI root of the app.  I configured VirtualBox's port forwarding to listen on 0.0.0.0 from audia, and when I connected to the VPN, my home computer (call it `starlet`) had its own /etc/hosts listing that used the internal IP of audia for dev.  The same URI from home would then get connected via port-forwarding to the dev VM.

This all changed when I wanted to test a SAN certificate and some redirection rules.  I didn't want certificate mismatch errors in Firefox, and I needed dev to think it was the production server so that it would use the production ruleset.  That became the underlying justification for devproxy.  After that point, dev had the production certificates, hostnames, and rules.  It had a host-only network added, which audia now used, and I took out the port forward.  (This was the problem behind getting Lost in the Complexity.)

But without the port forward, starlet can't reach dev anymore, only audia.  Of course, I came up with a solution:

(Despite what may be implied, the VPN isn't connected to starlet.  I just didn't feel like redrawing the whole tube.)


Monday, July 29, 2013

SNS driven deployment (architectural overview)

3 Sep 2015: a note about how we're using php-fpm instead of suEXEC now has been published here.  Now back to your original post...

One of the problems I faced with getting Auto Scaling up and running was, "If I can't just ssh into the one live server and issue a git pull by hand, how do I push code out?"

Normal people would use capistrano, or Paste Deploy, or something, extended to access their auto scaling group to locate the hosts to use.  Or build on Heroku or Elastic Beanstalk to begin with.  I, however, am clearly not normal.


Monday, July 22, 2013

Bootstrapping an EC2 Instance, 2013 Edition

In the interests of "not implying old posts on my blog are still state-of-the-art", here's a quick overview of how I manage EC2 instances at work, modernized.


Friday, July 12, 2013

Controlling Internal Iteration

Once upon a time, I read this post on iterators.  Yesterday, a solution struck me for absolutely no reason.

How do you stop internal iteration without non-local returns?  Channels!

Wednesday, June 19, 2013

TLS: all those DH modes and PFS

Advice is easy to come by, explanation less so.  What are all these acronyms, and what makes them secure, or not?

Tuesday, June 18, 2013

devproxy

Today, I'm pleased to announce the release of devproxy!  It's an HTTP proxy server written in Go (atop github.com/elazarl/goproxy) for QA/testing purposes.  It intercepts requests directed to your production servers and transparently connects them to a staging server of your choice—including HTTPS (CONNECT) redirection.

This lets your staging server perfectly mirror production, including the hostnames and certificates in use, without needing to elevate permissions to edit /etc/hosts every time you want to switch between production and staging.  Instead, you can switch the proxy on/off in your browser; I use FoxyProxy.

I'd like to thank Elazar not only for writing goproxy (it made my life a lot easier) but also for modifying it to support what I needed to do in devproxy.  I'd also like to thank my boss for letting me release this as open source.


Thursday, May 23, 2013

A Look at Failing Polymorphism

First, a brief recap of Steve Yegge's "When Polymorphism Fails" in case it moves again. Let's skip to the part where he builds an example in which polymorphism doesn't help the programmer, using a user-extensible online game as the premise.  A user wants to add an OpinionatedElf monster; how does she do it?
Let's say the OpinionatedElf's sole purpose in life is to proclaim whether it likes other monsters or not. It sits on your shoulder, and whenever you run into, say, an Orc, it screams bloodthirstily: "I hate Orcs!!! Aaaaaargh!!!" (This, incidentally, is how I feel about C++.)

The polymorphic approach to this problem is simple: go through every one of your 150 monsters and add a doesMrOpinionatedElfHateYou() method.

Gosh. That sounds insanely stupid.
Yegge then compares that to an alternative, implemented within the OpinionatedElf (who is the one doing the judgement in the first place):
public boolean doesElfLikeIt ( Monster mon )
{
    if ( mon instanceof Orc ) { return false; }
    if ( mon instanceof Elf ) { return true; }
    ... <repeat 150 times>
}
There's also the viable-in-Ruby approach of opening all the classes and adding the doesElfLikeIt method to each of the 150 monsters. But still, there's a lingering problem with all of the approaches so far:
If someone adds a Gremlin, your elf will be stuck screaming something like "Gosh, what's THAT?" until you can update his code to include a case for gremlins.
I ran into my own instance of this problem recently.