One of my most hated interview questions use to be “How many IPs in this subnet?”
I use to hate this question. I was reading a post on Reddit about some guy that went through the programming interview at Facebook and it made me remember the simple interview question I always hated answering. It always went something like this
How many usable IPs in a /24
Ok that is an easy one.. 256-2=254 not a big deal.. next!
Then they would ask
How many usable IPs in a /28
That is what usually made me say “Networking is not really my strong point” Well got that one wrong.. So I went out to fix this many many years ago. Well there’s an easy step you can do in your head.
All subnets going up are half of the one below it. So your /24 would have 256 IPs in it. So it would go like this
/25 = 128
/26 = 64
/27 = 32
/28 = 16
So there was my answer 16 IPs and 14 are usable. Its really that easy to figure out. Anything between /24 and /32 is easy to figure out if you can easily do the math in your head like that. You can do the oppsite if they give you a /29
/32 = 1
/31 = 2
/30 = 4
/29 = 8
Now there is also a little math formula you can use also.
So back to our question.. If we want to know how many usably IPs in a /28. We would go like
2^(32-28) - 2
Which would be
(2^4) - 2 = 14
That broken down is like saying
(2*2*2*2) - 2 = 14
When you toss exponents in it gets a bit rough but its easier if they tell you.. So how many in a /20
(2^(32-20)) = 4096
We won’t worry about usable in this case because it depends how you will subnet it off.
MongoDB: Remove an arbiter from a replica set
This isn’t really a straight forward task. From what I know in 1.7 there is a command but that is development only. So I’m running 1.6 and to see the config for my replica set I run
rs.conf();
I get the following output
> rs.conf();
{
"_id" : "core",
"version" : 3,
"members" : [
{
"_id" : 0,
"host" : "mongo1.domain.com:27017"
},
{
"_id" : 1,
"host" : "mongo2.domain.com"
},
{
"_id" : 2,
"host" : "mgmt1.domain.com",
"arbiterOnly" : true
}
]
}
Now I have two members to my replica set plus my arbiter. So I want to remove that so I can add another one. So I run the following
> use admin;
> cfg = rs.conf();
> cfg.members.splice(2,1);
> cfg['version'] = 4
> db.runCommand({replSetReconfig: cfg});
Then it will be removed. You can see my version was at 3 so I upped it to 4 so mongo will know there was a change. Now if I check the config I get the following
> rs.conf()
{
"_id" : "core",
"version" : 4,
"members" : [
{
"_id" : 0,
"host" : "mongo1.domain.com:27017"
},
{
"_id" : 1,
"host" : "mongo2.domain.com"
}
]
}
Install Chromium on Fedora
This is an easy one
Create the following file
/etc/yum.repos.d/chromium.repo
With the following contents
[fedora-chromium]
name=Chromium web browser and deps
baseurl=http://repos.fedorapeople.org/repos/spot/chromium/fedora-$releasever/$basearch/
enabled=1
gpgcheck=0
Then run the following
yum update
yum install chromium
Get Django-NonRel working with VirtualEnv
MongoDB is getting a lot of press recently. I stumbled across a pretty interesting project called Django-nonrel. This is an attempt to build non-relational databases right into mongodb. Before you could always use a 3rd party ORM or just use pymongo right in Django but then you were missing out on all the nice apps the community has created. So the goal of this project is to make it so you can keep on using those. Now as of writing this joins are not working but from what I know they are working on it.
So lets start off by creating a virtualenv environment. I will call my project photoblog
virtualenv photoblog
Now lets activate our virtualenv
source ./photoblog/bin/activate
Now we can install Django-nonrel
wget http://bitbucket.org/wkornewald/django-nonrel/get/tip.zip
unzip tip.zip
cd django-nonrel
python setup.py build
python setup.py install
Now lets install pymongo
pip install pymongo
Now lets install the djangotoolbox
wget http://bitbucket.org/wkornewald/djangotoolbox/get/tip.zip
unzip tip.zip
cd djangotoolbox
python setup.py build
python setup.py install
Now we have to download and install the django-mongo-engine
wget --no-check-certificate https://github.com/aparo/django-mongodb-engine/zipball/master
unzip aparo-django-mongodb-engine*
cd aparo-django-mongodb-engine*
python setup.py build
python setup.py install
So now lets create the Django project
cd ~/photoblog
django-admin.py startproject photoblog
cd photoblog
Now the only thing you really have to change to get a basic site up and running is the following file
settings.py
So edit that and find the block that looks like
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
And you want it to look something like
DATABASES = {
'default': {
'ENGINE': 'django_mongodb_engine.mongodb', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': 'photoblog', # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
'HOST': 'localhost', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '27017', # Set to empty string for default. Not used with sqlite3.
}
}
Then you want to add the following to your INSTALLED_APPS
djangotoolbox
Now you can sync the db to set it all up!
cd ~/photoblog/photoblog
chmod +x manage.py
./manage.py syncdb
You are all set!
Change get_absolute_url for the user object in Django
I completely overlooked this in the docs. So if you are here you either didn’t look in the docs or overlooked it also.
I was doing something like this
return (user.get_absolute_url(), (), {})
Now that sends the user to
/user/username/
I wanted the user to go to
/u/username/
So in your settings.py file just do this
ABSOLUTE_URL_OVERRIDES = {
'auth.user': lambda o: "/u/%s/" % o.username,
}
Tether your android phone to Fedora
I just dumped my IPhone for an EVO. I wanted it to tether my laptop. I know i can tether using IPhone if I jailbroke it. Why tether on AT&T’s awful network.
So I wrote a simple script for the EVO (should work on most androup 2.x phones also)
The first thing you want to is enable usb debugging mode on your phone
Settings -> Applications -> Development -> USB Debugging
Now you can download the following file as root
http://zcentric.com/tether.sh
Then run it
sh tether.sh
Then on your phone run the azilink application and start the service. Then you can run
service android-tether start
You should be all nice an tethered to your phone using your USB cable.
WSGI Holygrail run multiple versions of Python on same webserver
One issue hosting providers have is the issue with clients needing to run different version of python. One client might need python 2.4 and others might need 2.5. So in comes uWSGI
So this blog post will go over how to install uWSGI on RedHat 5 and making a uWSGI server for both python 2.4 and 2.5 at the same time for different hosts.
So the first thing you want to do is download the source
wget http://projects.unbit.it/downloads/uwsgi-0.9.6.tar.gz
tar zxfv uwsgi-0.9.6.tar.gz
cd uwsgi-0.9.6
Now make the 2.4 version
make -f Makefile.Py24
mv uwsgi uwsgi24
Now make the 2.5 version
make -f Makefile.Py25
mv uwsgi uwsgi25
Now you have two binaries compiled to run 2.4 and 2.5 for python
So now you run the binaries
./uwsgi -s 127.0.0.1:3031 --pythonpath /tmp/multi/ -w django_wsgi
This will run a uWSGI server for a django app that is in /tmp/multi with a django_wsgi.py file.
You can then run
./uwsgi25 -s 127.0.0.1:3032 --pythonpath /tmp/multi/ -w django_wsgi
At the same time and they play nicely.
My django_wsgi.py file looks like
import os
import sys
sys.path.append('/tmp/multi')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Gitosis with wildcard support
At OpenSky I wanted a way to put config files into git. I started using gitosis for the git server. This was all great but for each new server I had to add the following
servers/host.domain.com
Now that just stinks if you want to do it for a lot of servers. By default gitosis does not support wildcards. So we can’t use servers/* and anything pushing to git@ip:servers/hostn.domain.com.git would be accepted. I found the following patch online. I then forked gitosis to on GitHub to support this and updated the README file. So you can follow it there.
Setup DRBD for master/master
At my job at OpenSky we have a common NFS share that is failed over to a slave nfs node if the master dies. It was setup so that the slave would just rsync from the master. This was done to save time. Not that I have some time, I decided to finally setup drbd on the two nodes to keep the files always in sync.
So below are my nodes with hostnames/ips and drive information
Node1
host: nfs1.domain.com
ip: 192.168.1.46
partition: /dev/sdb1
Node2
host: nfs2.domain.com
ip: 192.168.1.47
partition: /dev/sdb1
So once drbd is installed setup the following file
/etc/drbd.conf
To look something like this. You will want to change a few things in red. Put this file on both nodes.
global {
usage-count yes;
}
common {
protocol C;
}
resource nfs {
meta-disk internal;
device /dev/drbd1;
syncer {
verify-alg sha1;
}
net {
allow-two-primaries;
}
on nfs1.domain.com {
disk /dev/sdb1;
address 192.168.1.46:7789;
}
on nfs2.domain.com {
disk /dev/sdb1;
address 192.168.1.47:7789;
}
}
I choose to use protocol C. You can see the following protocols below. Also the on nfs1.domain.com has to match the output of a hostname command
http://www.drbd.org/users-guide/s-replication-protocols.html
Now on both nodes you want to init the drbd partition. Make sure this is a blank partition. It will wipe out everything that is one it. I called my resource nfs. If you changed it the commands will be a bit different based on what name you gave your resource
drbdadm create-md nfs
You should get an output like
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
success
Now make sure drbd can be run on startup and start it up now
chkconfig drbd on
service drbd start
Once you start drbd on both nodes it will connect to both. If you just start one and not the other.. the other will wait for the second node to come alive.
You can now make a filesystem. Make sure it is a filesystem for clustering. I recommend ocfs2 but gfs2 also works.
Find the real MongoDB command for pyMongo
I am in the middle of writing a MongoDB plugin for cacti using pymongo and ran into a little issue.
In the Mongo shell this works
> db.stats()
{
"collections" : 19,
"objects" : 145971,
"dataSize" : 64785380,
"storageSize" : 129544960,
"numExtents" : 75,
"indexes" : 69,
"indexSize" : 25403392,
"ok" : 1
}
So in pymongo I tried
info = db.command("stats")
Then I got the following traceback
Traceback (most recent call last):
File "./get_mongodb_stats.py", line 68, in
main(sys.argv[1:])
File "./get_mongodb_stats.py", line 39, in main
get_stats(host, port)
File "./get_mongodb_stats.py", line 57, in get_stats
info = db.command("stats")
File "/usr/lib/python2.6/site-packages/pymongo/database.py", line 306, in command
(command, result["errmsg"]))
Then I remembered a nice part about the mongoshell. You can run the command without the () and see the function
> db.stats
function () {
return this.runCommand({dbstats:1});
}
So you do this in pymongo
info = db.command("dbstats")