MettaProgramming

Thoughts on Software and Technology

Archive for the ‘Ruby’ Category

Using Github as a Small-Scale CDN (w/Rails)

leave a comment

I love Github.

Like tomato sandwiches, Celtic music, beer, and programming- Github is something that, try as I might, I just can’t make myself sick of.1

Recently, I took the Git survey, and it contained an interesting question along the lines of “What do you use Git for?” The answers were things like “configuration files” and “large binary files.”

I use Git and Github for a lot- configuration files are one use (I love the “raw” path), but it was only a small percentage of what that list suggested, so I started wondering how else I could use it.

Today, I thought of an interesting way: Github as a CDN.2

If you know what a Content Delivery Network (CDN) is, you don’t want me to explain. If you don’t, then it’s good enough to say that it’s a way to server up pictures or other content from another server. It’s often used to, say, serve the main portion of an html page from a webserver, but serve the images, CSS files, etc. from something like Amazon to speed things up.

I recently finished work on The Great John Metta Branding Project and, like with so many projects, stored the images in Dropbox. Then, deciding I might want to version them, I stored them in Github. Then, just as I was starting to begin the rather annoying process of copying all these logos and textmarks to my various sites throughout the web and updating all the image tags, I thought to myself “Hey, if these are already in Github, and I can access the raw files, why don’t I just use that as the image source?” But I don’t want to have to remember the URL each time. What if it was somewhat dynamically generated?

A RESTful CDN system for a logo

This is exactly why I made johnmetta.com a Rails project, to play with stuff like this and then have a place to have it be live if I wanted to use it.

I’ve got a lot of different styles that my logo can take. Stacked, Icon only, textmark only, icon one-color grey, textmark one-color blue, etc. Ideally, I wouldn’t have to remember the path to each, I could type something like http://johnmetta.com/brand/icon/blue/transparent/logo.png3 and have the app return the image that is strictly the icon (no words) with blue coloring and transparency inside the logo (instead of the normal white).

Since none of these actual images is created on the fly, I created a sensible directory structure and embedded all the files in this structure, naming them all logo.png and putting the default logo in the top level. So the above image would be {base}/full/logo.png, while a version with the icon on top would be {base}/full/stacked/logo.png. A one-color version of only the icon might be {base}/icon/blue/logo.png

So I created a Brander class which would turn arguments into an appropriate path and added some new routes such as “brand/:type/:color/logo.png” and created a call to brander in the controller’s “brand” action that ends with a redirect to the returned URL.

It’s all really simple, but it allows me to have a url like http://johnmetta.com/brand/icon/logo.png and supply my logo, and http://johnmetta.com/brand/stacked/blue/logo.png for a one-color blue stacked logo. Then, if I update the colors (move the files, whatever) they update automatically. At a maximum, I just check in the changes and make minimal changes to the routes- but don’t have to copy files to servers.

A Good Illustration

Right now, the Brander class is pretty dumb- little more than a way to translate a route into the correct external URL. It was built up not as an illustration of how to accomplish “Github as a CDN,” but merely as a toy to test one way that it might be done on a small scale. It might be better done as a class where instance attributes make more sense, and I’ll clean it up a bit, but not much more than that.

Also, it’s cool to know that stuff like this can be set up so easily, and for my uses- where bandwith might reach a whopping few requests per day, it’s useful while being low impact. But for a real CDN, you’d still want to use something like AWS- or at least talk to the Github guys before swamping their webservers.

  1. I’ve tried for the past two summers to make myself sick of eating tomato sandwiches. I just can’t. []
  2. The title is with Rails because that’s what I used, but it would take 2.4 minutes to make this a “With Django” or “With Lift” example []
  3. Actually having “logo.png” is unnecessary, however, sometimes the software using the URL will depend on that, so I just made it convention so that I don’t have to think about when sometimes is. []

Written by john

September 15th, 2010 at 6:11 pm

Posted in Ruby

Tagged with , ,

So you want to hire a ninja, do you?

3 comments

I took a trip to Portland recently to traipse through OSCON. I was mostly in the exhibition hall with all the great schwag and company booths– many which had posted job announcements. While there, I was once again frustrated by a trend I keep seeing. The trend can be described as an “arms race of job announcements,” and has gotten to the point where it’s difficult to find a development job listed by a company that is not seeking a “ninja,” or a “rockstar,” or some similarly absurdly described candidate.

Smart and Gets Things Done

As best I can tell, this trend really took off– even if it didn’t start– with Joel Spolsky’s blog article titled “The Guerrilla Guide to Interviewing.” In that article, he stated that there was one primary requirement for working at Fog Creek Software: “Smart, and gets things done.”

His basic argument, with which I tend to agree, is that it doesn’t really matter what your past qualifications are as much as it matters that you can do to things: 1) Learn shit, and 2) Actually do shit.

His point? If you can’t learn, you’ll be stuck trying to write software in Visual Basic and someone will eventually shove you off of a roof out of frustration. Furthermore, if you don’t actually DO anything, but rather just talk about it, or think about it, or tell others why you could do it better– then you won’t even write software in Visual Basic. You won’t write any software at all, and someone will eventually shove you off of a roof out of frustration.

But if you can learn, it doesn’t matter what you come into the job knowing, because that’s merely a starting point. It’s how your knowledge and skills translate over time that’s important. You can learn <insert whatever you need to do your job here> quickly. I say quickly because you are a DOER, and doers always learn new stuff, so they can DO more stuff.

The most important thing here: The job will probably change, and when it changes, it’s the people who can LEARN, ADAPT and DO that will help the company succeed. The person who came to the job with one incredible skill but can’t learn probably has that one incredible skill in a stupid technology like Visual Basic, and someone will eventually shove–

well, you get the idea.

The problem with catchy words

So, herein lies a bit of the problem. Joel also talks about hiring the best people, treating them like “rockstars,” etc. Again, I think he has a point, but that there are a great deal of people who are stupidly picking up the hot new terms like “rockstar” and “ninja” and using the words, basically, without using their brains.

I see them a lot. Those posting that sound all hip and cool: “Are you a Python Guru?” or “We’re looking for a Ruby Rockstar for-” or “We want a PHP ninja to-” Everytime I see one of them I want to slap them in the head with the nearest O’Reilly book and then vomit.

This type of job posting proves one thing to the very people that you want hire: That they don’t want to work for you.

Why?

Because the very people you want to hire are the ones who describe themselves as “hard working” or “with a lot to learn” or even “not as good as many, but loyal, friendly and likes to learn new things.”

Do you really want to hire a ninja?

What’s a ninja?

It’s such a stupid, overused buzzword! Do you even know what it means? It’s either an assassin or a stupid 14 year old jumping out of a dumpster brandishing a medieval sword.

You don’t want either of those things!

Ninja: It's a word that's THIS overused

Yes, there’s some evidence that a well trained ninja was, if absolutely nothing else, a competent assassin (though the Samurai made fun of them). A ninja is basically a person who does one single thing really well, they kill people, and the rest of life- including the whole “getting along with people” part- they could give a rat’s ass about.

Human interaction to a ninja is “kill them!”

Conflict resolution to a ninja: “Kill them!”

For those who miss my subtly: A ninja programmer’s response to pretty much anything is going to be this: “Do it my way and no-one gets stabbed in the face with my medieval sword.”1

Think about it. Do you really want to hire someone who does one single thing really well? To the exclusion of things like “showering” and, say “talking to other human beings?”

Ninjas are Zombies!

Here’s a neat trick: think of another stupid, overused buzzword: Zombie. What if I told you that ninjas are just zombies with black bags over their heads?

They do one thing really well: kill people (eating their brains- mostly the brains of your team if you hire them), and they could give a rat’s ass about things like “human interaction” and “conflict resolution.” What’s their solution to everything? “Kill them! (and, since we’re here, we could maybe snack on their brains too…)”

Ninjas are zombies! They’re mindless idiots going around trying to do one thing.

That’s it.

When you say “I want a ninja” you’re saying “you can be a complete asshole, refuse to learn anything new, refuse to respond to other human needs or the needs of the business, and also be a social trainwreck. Oh, and you don’t really need to know, or care, about 90% of programming or computer work, but if you can sit in your hole and <do that one thing well> and not talk to anyone, you’re the guy for us!”

You want a ninja-zombie as your lead developer, don’t you? Admit it.

Rockstars: They go to 11

Alright, I think you get my point, but let me touch upon rockstars for a moment. Here’s another place where I think Joel’s point was completely missed by a lot of people. Joel says “hire the best people you can find and treat them like rockstars” and in pure politician-like “I don’t really want to put any actual cognitive thought into this process, so I’ll just pull a buzzword”-style, job announcements start popping up for undefinable qualities such as “Ruby Rockstar.”

You want these guys in your company?

The mistake here is that all the corporate bozos think “Hey, ‘Rockstar’ is the current buzzword, so I’ll use that too!” without stopping to think about one thing: “Rockstars don’t usually make the best employee material.”

Think of the words “punctual” and “hardworking.” Okay, now, keep those words in your head, and think of the word “rockstar.”

Yeah, your neck hurts doesn’t it?

See what happens when you take things out of context? Joel’s statement was “treat them like rockstars.” In otherwords, treat them like they mean something, like they matter, like the company depends on their happiness… so they will be happy… and do really good work… and make you more money.

The line was emphatically NOT “Make them into rockstars.”

Seriously! Think about your average caricature of a rockstar.2 They show up late, drunk, stoned, with a 16 year old’s bra stuck to their belt, and give you a loud, shitty performance of something they don’t feel like playing before hopping back into the bus for more sex, booze, and food.

Okay people, repeat this after me:

“I don’t want to hire a Rockstar!”

A rockstar is probably worse than a ninja, because at least a ninja- or a zombie, for that matter- can do one freakin’ thing well. The only thing the rockstar can do is pray to god that the sound team can mix together the shit they call a studio performance, and that the stage crew can hit blow the fireworks early to cover the guitarist tripping and falling because they’re too freakin stoned to remember that there’s a drumset behind them.

They think of themselves as the best thing that’s ever happened to you, and if you tell them otherwise, they’ll freak out.

Rockstars look good. Full stop.

You know who the rockstar is? It’s the young programmer I met at the Open Source Bridge conference who immediately berated me for using a different database strategy than him– without ever stopping to listen to the problem I was solving, to hear about my application’s design, or to learn why I would choose one over the other.

I was wrong, they were right, and I should really just stop being stupid and do it their way.

Yeah, that’s who I want on my team.

Fucking rockstars.

Are you an incompetent programmer with an overblown sense of self-worth?

Here’s the part that bugs me the most: The people posting these job announcements are actively selecting for people with a tendency to overstate their abilities while understating their faults.

It’s called the Dunning-Kruger effect and it’s well documented in both the scientific literature andpopular journalism.

The basic Gist is this: Incompetent people tend to overstate their abilities and think they are amazing, while highly competent people tend to downplay their skills and think that they are less than amazing.

And you know it’s true.

Go pick the first male rockstar-ninja-zombie programmer you can find and I’ll pick the first quiet, understated female programmer I can find. Then we’ll see which one can actually shut the hell up about how great they are and get something done.

The best people for the job are not the ones who are going to feel comfortable applying for the “Amazing Rockstar!!1!” position for the very reason that they are the ones that you want to hire: because they are too busy being amazed at all the stuff they don’t know to be rockstars who tell you everything that they do know.

They don’t think they know everything. In fact, with everything there is out there, they realize that they know basically nothing. Most importantly: They know that there’s a lot to learn, and they are trying to learn it.

The rockstars? The ninjas? They already know it, and they’ll tell you.

In fact, They’re more than happy to tell you how much they know.

Every single time you interact with them.

Folk Developer: Will learn and be nice for food

I don’t apply to any of these positions because, while there are a lot of things that I am and can do, there are certain things that I am emphatically not. A partial list of the things that I’m not is:

  • Rockstar
  • Ninja
  • Zombie
  • Best person in the world at <fill in whatever you want here>

Me, I’m not any of that. And that makes me think, from the majority of jobs I see lately, that I won’t be good enough to make the cut. And let’s face it, if they’re advertising for a rockstar, then I am probably not, because I do a lot of things competently, not one thing better than everyone else including you.

See here’s the thing: I’ve been programming for 25+ years, I’m competent in at least 10 different languages, and really good in at least 4.3 I’ve built everything from robotic control systems to mathematical models, from spatial applications to social web applications. I’ve taught programming, and am about to do so again, and I do other things like start a Ruby users group.

By many-if-not-all accounts, I’d be one hell of a developer to have on a team; yet many teams are seeking rockstars.

I am not a rockstar.

I’m not the guy on stage with lights and explosions and a screaming electric guitar.

I’m the guy who goes to a party and sits on the couch singing a song on a guitar. A really fun song, with really good guitar work, but not anything that needs lights and explosions. I may also pick up a banjo or back someone up on a number of other instruments, but mostly I just stay at the party and hang out with people.

No lights. No explosions.

I’m a folk developer.

I’m a seeker, I’m a learner. I’m a hard worker who will spend his free time coming up to speed on a technology for curiosity as well as success. I’m loyal, I’m friendly, I’ve got a sense of humor and would much rather laugh at myself than at anyone else. I spend my off time programming, like lots of people who love programming, but I also spend my off time playing the Irish flute and banjo, cycling, brewing cider and mead, working in community theater, and lots of other social pursuits.

Despite this (or, rather, because of it) I see myself as little more than “a decent programmer who’s probably not as good as most, but might be better than some.” In fact, I don’t have enough fingers to count the number of jobs I’ve actually turned down because I thought that I was probably not good enough– only to find that someone else was hired whom I actually know that I can outperform.

I am not going to apply for a job as a Python ninja or a Ruby Rockstar, because I’m not a ninja or a rockstar. I’m a person who knows a heck of a lot less about Ruby than many other Ruby programmers.

I’m a person with a lot to learn.

Exactly zero of my qualities describe a rockstar.

Are you an incompetent company with an overblown sense of self-worth?

And I know that’s also true of many of my developer friends and colleagues. Companies select for people who are not them.

Here’s the clincher. Most of those companies who are hiring ninjas and rockstars are probably doing so because they see themselves as ninja and rockstar companies.

They are the companies that say things like “do you want to work in our cool-ass company where everything is better than any other company you’ve ever worked for, where we have foosball all day and are all awesome and badass about everything we do?”

Sound familiar? I’ll bet it does.

It sounds like a rockstar of a company.

  1. No, don’t ask your ninja programmer why they have a European weapon, you’ll get stabbed in the face. []
  2. which is all we’re really talking about in either case- neither Joel or you are talking about Dar Williams, here. []
  3. 5 if we count Ruby, which I’m learning more about every day []

Written by john

July 28th, 2010 at 3:36 pm

Stop being stupid about belongs_to!

2 comments

This is just a post that may help me stop being stupid. Writing it may help carve it into the permanent portion of my memory instead of the “forget about it and then periodically have to think twice and remember that you did something stupid” portion.

It’s a small thing, more of an annoyance than a real problem. Something like my tendency to forget “end” after blocks (a Python holdover) and to assume that zero equals false (a sort of “everything else” holdover).

It boils down to this:

belongs_to is singular,  you stupid dipshit! Stop being a mindless screwhead and remember that for a change, John!

Honestly, it only takes me a second once I get the ever familiar error, but it’s just better to not get the error at all, right? Efficiency and correctness.

If anyone reads this and runs into me later, I wouldn’t mind if you repeat that statement to me.

More reminders couldn’t hurt.

Written by john

July 21st, 2010 at 1:38 pm

Posted in Ruby

Tagged with , ,

Quick, “random records” module

leave a comment

There are plenty of times when I want to grab either one or many random records from a database in Rails. For instance, one random user, one random post, 5 random items, etc. Honestly, it’s one of those things I do in nearly every app I’ve written, so a while ago I created a module to add to any ActiveRecord class that gave me one() and some() methods. This way, I can just include Randomizer and have the methods. Everyone probably already has their method– I actually got this from somewhere else and modified it a bit– I figured I’d post mine in case someones searching the innerwebs.1

[gist id=450723]

  1. It’s one of those things that could be in a plugin or gem, but I’m getting really sick of gems and plugins that carry all the infrastructure to support being gems or plugins when they are really simply a wee bit of code in one small file. Thus, I’m starting to just publish Gists and add them manually to my lib directory. They’re not really gems– they’re more like ungems. Maybe shards. []

Written by john

June 23rd, 2010 at 4:46 pm

Posted in Ruby

Tagged with , , , ,

Secure password generator-as-manager without single-point failure

2 comments

Ahh, security. It’s it’s like flossing and using condoms. We all know we should do it but… well, it’s business time!

We’ve all got the same issues. “Use strong passwords!” which means “don’t use just words” is something we all try to take seriously, but it just ends up being something like “c00lp455″ with even the most basic cracker program would handle easily– replacing letters with numbers was maybe a good strategy in 1988, but you might as well just use “coolpass” today, because that’s not any easier than using numbers for any attack.

“Don’t use the same password often,” “Use passwords with enough entropy (randomness),” “Use passwords longer than 8 characters with upper and lower case letters, numbers AND PUNCTUATION!!”

Whatever.

It basically comes down to this: We all have one password we use for freakin’ everything, and that password is probably something like “mysillyp455.”

Sigh.

I’ve been wanting to get away from this lately, but have been generally disappointed at the options.

There are dozens of password managers out there, and hundreds or thousands of password generators. I have issues with all of them, and recently decided to address them in a bit of a crazy way: By completely re-thinking how I handle passwords.

Password generators suck

You know it’s true. They come up with the most ridiculous passwords that you’ll ever see. Who the hell is gonna remember ’5+b(*|$1e8+8@’ is their password?

Oh, right you want pronounceable passwords, because ‘m4k1tw0rk’ is going to work better than ‘makeitwork.’ Right. See above.

I mean, they do their job, sure, but password generators generating random strings are not really very useful to me, because I’ll never be able to recreate the password, which means I have to write it down somewhere or store it in a password manager…

Password managers suck

Yeah, I know, you’re a dedicated 1password user and you think I’m an idiot. It’s a decent solution1 but it, like any manager, still suffers from some serious flaws.

One is, of course, that if you’re somewhere or somehow don’t have that manager available, it’s absolutely impossible to get your password. This has recently happened to me while trying to use an app called LastPass, which generated really nice, ridiculously hard passwords for all kinds of stuff, that I could then never remember and I couldn’t get later when I screwed up my master password.

Reminder emails galore!

Here’s another problem: My passwords are stored on somebody else’s webapp database. Oh, sure, they’re stored ‘securely,’ but how the hell do I know that’s true (read the TOS people, they limit their liability for a reason).

If the pentagon can get hacked, some 24 year old start-up geek is certainly vulnerable.

Single points of failure suck

The biggest things about all of these is the ‘single point of failure’ issue. Password managers store passwords in encrypted files, so that’s nice. But what if someone gets your all important 1password that secures all your other passwords? You are, in a word, fscked.

So, the basic problem with all of these is that they are not actually as secure as we think, and when they are, they’re not easy. So we either have secure and hard as hell, or we have easy and fundamentally flawed, right?

Maybe not.

Password generation as password management

Okay, no lie, this came to me while somewhat tipsy and pouring down beer at a local pub:

What if your password wasn’t stored anywhere, ever. What if you could simply have a way to securely recall those ridiculous passwords that generators come up with out of thin air?

Think about it. 5+b(*|$1e8+8@ is probably a pretty damn secure password– if you used that for anything, you’d be pretty safe, but you’d never remember it. But what if that was, in a way, mnemonically generated?

Enter Passfish.2

Passfish is a program (actually, it’s an idea)3 that generates passwords from the combination of words, a secret key file, and (optionally) name and passphrase parameters. Using this combination of items, Passfish will generate a high entropy password.

$ passfish 'name@email.com'
 9!b%e+70

Now, that password is not stored anywhere, not in any encrypted file, nowhere.

Furthermore, if you use the Bash shell’s ability to ignore certain commands, that won’t even be in your Bash history. No-one can get it in a file, no-one can see what you’ve typed. It’s ephemeral. You call it up, and then it goes away.

But it’s still insecure as hell, right? I mean, anyone can figure out that name@email.com turns into SOMETHING.

Generation and modification of hashes on the fly

Keyfiles solve this. When you have a private keyfile, the string name@email.com is combined with the contents of this file, a hash is generated from that combined string, and the hash is modified in a repeatable way. This means that you can have super simple “passwords” (e.g. name@email.com) and even write them down on your forehead, and no-one will be able to generate your actual password without having your same keyfile.

But wait, there’s more!

$ passfish 'email' --name 'work'
(|@+#^7b
$ passfish 'email' --name 'home'
$1e8+8@

You can specify an additional parameter, a name. This allows you to increase the security because you could have the same “password” for multiple accounts. You can also have passphrases:

$ passfish 'email' --passphrase 'I hate Dirty Dancing!'
$1e8+8@

This allows even more security!

There’s also a length parameter:

$ passfish 'email' --name 'work' --length 13
$1e8+8@$1e8+8

Simple mnemonics for complex passwords

One of the things many people do when thinking of passwords, is create devices that they use in ALL of their passwords. For instance, start with an @ and end with a $, then capitalize the first letter, so a password could be something like ‘@Email$’.

What Passfish allows you to do is to create similar mnemonics, but use them wisely to create truely complex passwords. For instance, it’s a website that I use at work called “workstuff.com

$ passfish "workstuff.com" -n "website" -p "at work"
$1e8+8@

Thus, the password is not stored anywhere, but I have an easy way to remember it.

No single points of failure

This way, even if someone steals my computer, they can’t get my passwords unless they have ALL of the following:

  1. The password identifier
  2. The understanding that I’m using some stupid geeks weird Passfish program
  3. Access to my private key file (which could be any file I choose)
  4. Knowledge of the name, passphrase and password length

Rather than a single point of failure, there are multiple points for each password, because even if someone got your private key file figured out, they’d still have to spend considerable time getting each password– and access to one password makes it no easier to access another password! It’s not an all-or-nothing proposition.

The Status & Future

So, what’s the status? Well, it’s currently an open source application on Github, and it’s little more than a proof of concept. All it does now is combine all the parameters together into a string, hash it, and modify the hash. Pretty stupid, I know. (The plan is to do things better, like use the passphrase parameter to strengthen or change the hashing, etc.)

And as for the “but that’s stupid and hard” people, the other plan is to create apps that tie in with this underlying generator for things like Android and LaunchBar. For instance, a LaunchBar plugin that lets you type the identifier, name and passphrase, and then automatically copies the generated password to the clipboard, so that you don’t have to even see it, much less go to a terminal window to use Passfish.

So, it’s new, it’s still pretty dumb, but as a proof of concept, I throw it out there as an idea, knowing that– because it’s open source– any serious vulerabilities or blindspots will be illuminated.

Check it out, fork, modify, correct. Throw me ideas and comments or ignore it altogether.

  1. or at least it would be if they’d make a freakin’ Android app! []
  2. Disclaimer: this is a proof of concept. A crazy scheme. It needs work, so I wouldn’t jump into using it. At least not yet. []
  3. actually-actually, it’s planned to be an algorithm, but right now it’s simply a quick hack as a proof of concept []

Written by john

June 16th, 2010 at 5:34 pm