Playing with Rust

I’ve been hearing nice things about Mozilla’s programming language Rust reaching version 1.0, so as the curious little sysadmin I am, I decided to see how fast it is compared to bash and python. I picked these two because they are without a doubt the two most used languages by server monkeys.

First, let’s look at the scripts:

$ cat hello.rs 
fn main() {
    for x in 0..1000000 {
	println!("{}", x);
        println!("Hello world!");
    }
}

$ cat hello.sh 
#! /bin/bash
for i in {1..1000000};
do
	echo $i;
	echo "Hello world!";
done

$ cat hello.py 
for x in range(0,100000):
	print x
	print "Hello world!";

Each of these will print both the position in the 1,000,000 iteration loop, and then it will print hello world. Nothing more to it, we simply get 2,000,000 lines out of all of this. For my next trick, I then ran each of the commands one after the other with a time command. I decided to add the time taken to compile the rust to see if compiling made much difference.

Well the results are in, and you can see them for yourself. Bash is slow, obviously because it has to fork the echo command many times over. Next, Rust comes in at second, taking 0.504s to run after a 0.353s compile time. This may be around 12x faster than Bash, Python comes in at 5x faster still.

$ time rustc hello.rs; time ./hello > /dev/null; time ./hello.sh > /dev/null; time python hello.py > /dev/null;
rustc hello.rs 0.33s user 0.03s system 100% cpu 0.353 total
./hello > /dev/null 0.34s user 0.16s system 100% cpu 0.504 total
./hello.sh > /dev/null 6.14s user 0.29s system 100% cpu 6.420 total
python hello.py > /dev/null 0.10s user 0.00s system 91% cpu 0.117 total

I guess what I’m trying to say is this: don’t go switching languages just yet.

Welcome to the new Thor

Marvel this week Marvel announced that a new Thor book will introduce the well loved character as a Woman, and the internet exploded with the predictable comments how about this is simply pandering to women.

My questions to those people are: And? What is the problem with pandering to women? What is it about comic books that mean that they are completely owned by men? Why is pandering so bad when it’s done to someone that isn’t you? For decades men have been the pandered, with sports constantly being shown on TV, magazines with women scantily clad on the cover, and a comic book industry which has confessed on only focussing on them. Now that men are being told they’re no longer the focus, they’re getting quite angry.

People keep reading this story under the delusion that old Thor is out and new Thor is a woman, and that the character has always been a woman, and we must accept this. Well I’m sorry to those people, but that’s not what was announced, because the old Thor is simply no longer worth of Mj√∂lnir, and for all intents and purposes has been fired from the job. The next available candidate has stepped up and SHOCK HORROR this person is a woman.

I really hope that these people are never put in charge of hiring and firing in a company because they are exactly the type of people that will say “the last person to do this job was a guy, so we’ve got to have another guy to take his place,” completely ignoring all of the progress society has made in giving women equal chances in the work place (we’re not there yet though).

This is not just sticking boobs on a character, and I have to ask, why do people keep using that as an excuse to be outraged? What is it about the application of breasts makes people so angry? I thought guys were supposed to like that sort of thing (over-generalisation, I know), yet here they are complaining about them. They’re being pandered to with big boobs and they’re still not happy!

We can have other arguments. She’s white and blonde, of which there are many characters exactly like this, but I’m not going to shake my fists at Marvel just yet, not when the Ms Marvel, the story of a young, Pakistani teen is doing so well, and that I’m loving every minute of it. There’s a way to go in terms of diversity, but we shouldn’t knock one progression (+1 to female characters) because it doesn’t fill all the diversity criteria.

LLX2014

Oh my word. I think I finally have 10 minutes to sit down and actually write something. Unfortunately, I don’t have any images to go with this post to make it more exciting, so you’ll just have to make do with a wall of text.

This week was absolutely, unequivocally, spectacularly amazing.

For the first time ever, I took the plunge and went to a Lindy Exchange – the London Lindy Exchange, to be exact. For anyone wondering what that is, well was the entire bank holiday weekend filled with social swing dancing around London. Starting on Friday, there was an evening of dancing at the Camden Centre. Then on Saturday and Sunday there were a couple of events each, starting at 2 in the afternoon, taking a break for a couple of hours at 6, and then back to dancing from 8 until… well until late. Or early. It depends how you want to look at it, really. Finally, on Monday there was a even from 2pm till 6, you know, to help everyone wind down a little.

To cut to the chase, I had an overwhelmingly enlightening time at all the event’s the weekend had to offer. Although I didn’t stay as late as some people because I like to sleep while it’s still dark, and feed my birds first thing in the morning, I felt like I had squeezed almost everything out of the events that I could physically handle.

I started on Friday night watching other dancers from the wings, wondering how I could ever learn to be so good as all those around me. I surely did feel like I was a mere pleb compared to the high lords of swing that could be found on the beautifully polished dance floor. Little did I realise though, being in the company of such amazing dancers rubbed off on me, and pretty darn quickly too.

It was really on the second night that I started to realise how much I could let go of any of my insecurities, through caution to the wind, and open my mind unto the almost infinite possibilities that I could conjure. Lindy turns, swing-outs and changing places are the staple of any dancer, but soon I found myself trying out moves that I’m not even certain have names!

Partners came and went throughout the night, and I found myself being thanked for each dance with bigger and bigger smiles, and I reciprocated in kind, and who wouldn’t? Not after dancing with such amazing ladies, young and old.

The biggest highlight would have to be the band that played on Saturday and Sunday nights – Gordon Webster and Friends. Lindy hoppers are well known for dancing no matter what, but when everyone stopped dancing, I knew something special was happening. The band played an entrancing and colossal rendition of Joshua Fit the Battle [linked: Hugh Laurie version from Let Them Talk], which sent everyone to the front of the dance floor to crowd around the stage to watch in awe as masters of their art performed with their entire souls.

The entire weekend progressed, and I feel that progressed with it, reaching new highs, learning new (old) moves and new (old) music. As I sit and write this, I’m listening to playlists of swinging songs that had never been part of my music collection before, but has started to become a staple of my listening habits. I start to think of moves I’d like to do when I stand on the train platform, and was even caught busting a few of them out while waiting for the bus on Monday afternoon.

Bring on the next exchange!

 

Rackspace Cloud DNS api

I used to use dyndns to point one of my subdomains to my home PC. That was great, but dyndns has started requiring that you log in every 30 days to continue to renew your free account, which is a massive ballache. Then I remembered that I’m a Racker, Rackspace have cloud DNS for free, and I have python in my utility belt. So this was my response to dyndns. Up yours, guys.


#! /usr/bin/env python
# dnsr

import httplib
import json

USERNAME="username"
APIKEY="apikey"

conn = httplib.HTTPConnection("someipservice.com")
conn.connect()
conn.request("GET", "/")
resp = conn.getresponse()
rText = resp.read()
homeip = rText
conn.close()

authJson = """
{
"auth": {
"RAX-KSKEY:apiKeyCredentials": {
"username": "%s",
"apiKey": "%s"
}
}
}""" %(USERNAME, APIKEY)

conn = httplib.HTTPSConnection("identity.api.rackspacecloud.com")
conn.connect()
conn.request("POST", "/v2.0/tokens", authJson, {"Content-Type": "application/json", "Accept": "application/json"})
resp = conn.getresponse()
rText = resp.read()
rJson = json.loads(rText)
token = rJson["access"]["token"]["id"]
account = rJson["access"]["token"]["tenant"]["id"]
print "Token: %s, Account: %s" %(token, account)
conn.close()

conn = httplib.HTTPSConnection("dns.api.rackspacecloud.com")
conn.connect()
conn.request("GET", "/v1.0/%s/domains" %account, headers={"Content-Type": "application/json", "Accept": "application/json", "X-Auth-Token": token})
resp = conn.getresponse()
rText = resp.read()
rJson = json.loads(rText)
#print json.dumps(rJson, indent=4, separators=(',', ': '))
conn.close()

for dom in rJson["domains"]:
if dom["name"] == "mydomain.com":
domainID = dom["id"]

print "domain id: %s" %domainID

conn.connect()
conn.request("GET", "/v1.0/%s/domains/%s" %(account,domainID), headers={"Content-Type": "application/json", "Accept": "application/json", "X-Auth-Token": token})
resp = conn.getresponse()
rText = resp.read()
rJson = json.loads(rText)
#print json.dumps(rJson, indent=4, separators=(',', ': '))
conn.close()

for subdom in rJson["recordsList"]["records"]:
if subdom["name"] == "subdomain.mydomain.com":
subdomainID = subdom["id"]

print "domain id: %s" %subdomainID

conn.connect()
conn.request("GET", "/v1.0/%s/domains/%s/records/%s" %(account,domainID,subdomainID), headers={"Content-Type": "application/json", "Accept": "application/json", "X-Auth-Token": token})
resp = conn.getresponse()
rText = resp.read()
rJson = json.loads(rText)
print json.dumps(rJson, indent=4, separators=(',', ': '))
conn.close()

dnsip = rJson['data']
print "Home ip: %s" %homeip
print "DNS ip: %s" %dnsip

if dnsip == homeip:
print "IPs are the same. Exiting"
exit(0)

requestJson = """
{
"data": "%s"
}
""" %homeip

conn.connect()
conn.request("PUT", "/v1.0/%s/domains/%s/records/%s" %(account,domainID,subdomainID), requestJson, {"Content-Type": "application/json", "Accept": "application/json", "X-Auth-Token": token, "Content-Length": len(requestJson)})
resp = conn.getresponse()
print resp.status, resp.reason
rText = resp.read()
print rText

Now all I need to do is run a cron job every hour or so, and my IP address will update automatically.

Hardening my servers by using ssh ProxyCommand

Host internal
User me
HostName internal
ProxyCommand ssh me@gateway nc %h %p 2> /dev/null

I decided to use the above to jump on to my web and mail servers from my monitoring server, which contains nothing but nagios and nagstamon.

Why I’m glad I picked btrfs

btrfs subvolume snapshot @mysql @mysql-backup

That’s why I’m glad! When I want to do backups, I don’t have to lock a single table. Intstead, I just perform an instant snapshot on my db partition, and the back up the snapshot at my leisure.

I’ve just performed a test of it, and found that it quite happily restores the database without any errors.

Hooray for btrfs.

So Rackspace Happened…

…and all I can say is that I’m loving it.

Ok, so the commute is a bit mental, but that’s OK. It’s not a difficult commute, merely a tube and then a train, and it is certainly is very comfortable because I have a seat all along the way. I’ve spent most of my time listening to the Raising Steam audio book.

But back to the company itself. I realised today why I’ve been enjoying it so much. It’s not because it’s in a great office. It’s not because the food is cheap. It’s all because I’m no longer at the end of some chain or hierarchy.

In Engine I was just the sysadmin at the end of a long chain which included techs, creatives, account handlers, etc. Very few people had any reason to come over and talk to me, which, I felt, meant that very few people would simply wonder over to talk to me. It was quite similar in Transact. No one would really talk to me because I was the IT guy. I had no real connection with anyone in the company as a whole because the only excuse to talk to me was because something was broken, which is a bad way to have any kind of relationship with your co-workers.

But in Rackspace it’s all very different. I’m now part of a team, which is part of a large department, who all rely on each other and work with each other all day every day. I’m no longer at the end of a chain, instead I am (or at least will be when my training is complete) a fully functional working part of the mechanism that keeps the company going.

Yesterday, there I was just sitting at my desk, and someone came over to my desk.

“You’re new aren’t you? On the Linux team?”

“Yup, I’m Matthew, pleased to meet you”

“Taylor”

And so the conversation went on. How nice, I thought, someone spotted I’m the new guy and came over to say hi! As he walked away, I wondered who he was and what he did in the company. Then it dawned on me. The day before, I’d sat through the company meeting, and remembered someone called Taylor had done some talking, so I looked him up.

Holy crap. My first week and the freaking president of a 5000 strong company noticed me, knew that I was new and thought to say hi. No one that high up, in any of my previous jobs, had ever taken the time out of their day to just wonder around and say hi to me.

I think I’ve found my new home.

Always mock Adobe

10:44 < SuperMatt> where are you going to next, fanners?
10:45 < fanboy> Adobe
10:45 < SuperMatt> fanboy: cool... shall I give you my password now, or will you just extract it from the db?
10:46 < fanboy> I actually loled smatty
10:46 < fanboy> :)

Why I love using a key-value store

CREATE TABLE objects (
    id integer NOT NULL UNIQUE PRIMARY KEY,
    type text NOT NULL,
    "timestamp" timestamp DEFAULT now()
);

CREATE TABLE attributes (
    id integer NOT NULL,
    key text NOT NULL,
    value text,
    "timestamp" timestamp DEFAULT now()
);

Two tables, that’s all I need for a database that can hold any data I want without having to worry about updating the schema.

The objects table stores an id and the type of object it is. For instance, if we have a user in the DB, the id could be 1 (I’m admin, so why wouldn’t it be?), and the type can be set to ‘user’.

Continue reading Why I love using a key-value store