Audrey Multi-instance Deployment Demo

January 13th, 2012

A screencast I created  has landed on youtube. It demonstrates using audrey to launch a multi-instance deployment in EC2 using the Aeolus Project.

More info at
https://www.aeolusproject.org/
https://www.aeolusproject.org/audrey.html


The “check computer” light

October 26th, 2011

On my way to work this morning my car’s check engine light came on. This is not an uncommon event, my car eats batteries and when the battery starts to fail and the car has trouble starting the light will come on. A few days later it generally clears itself. The couple times that the light has not cleared itself I have actually had to take it in to have it looked at.

This morning when it came on I suggested to my carpool buddy that I wished a built in feature of cars was to tell me why the light came on. Seems ridiculous to make me take it to someone to tell me what’s wrong with my car. Imagine if we had to take our computers to someone any time there was an error message in /var/log/messages. What a pain.

Ha! Take that car analogies of computers! I just made a computer analogy of cars!

I know you can buy those readers that will tell you the error codes. Although, my car is a VW that takes a non-standard reader and is more expensive than the common ones. Ah, German engineering.

(For my non-linux cohorts, /var/log/messages is the system log in linux)


coverage.py

October 25th, 2011

I was working on updating some unit tests today at work and was wondering if there was a way to measure the unit test coverage on a set of code. A single google search returned the ability for you to tell the exact test coverage your unit tests achieve and the exact lines of code that are not included in your coverage.

Enter coverage.py: http://nedbatchelder.com/code/coverage/

I’m on fedora so $ yum install python-coverage installed it for me.
To get the details suggested above you need only run two commands.

~/git/audrey git:(oauth*)➤ coverage run audrey_start/test_audrey_startup.py
……………
Ran 15 tests in 2.601s

OK

The coverage run command executes your code just as if you had executed it without coverage.py, but has generated data about the code it’s executing as it’s running. You can see here I’ve executed this code’s unit test script. Next you display the report data:

~/git/audrey git:(oauth*)➤ coverage report audrey_start/*.py
Name                               Stmts   Miss  Cover
——————————————————
audrey_start/audrey_startup          472    270    43%
audrey_start/test_audrey_startup     217     19    91%
——————————————————
TOTAL                                689    289    58%

~/git/audrey git:(oauth*)➤ coverage report -m audrey_start/*.py
Name                               Stmts   Miss  Cover   Missing
—————————————————————-
audrey_start/audrey_startup          472    270    43%   126-132, 186-216, 237, 241-243, 247, 288, 352, 379, 382, 388, 414, 456, 544, 558-559, 585-601, 609, 630, 640, 654-689, 700-730, 739, 747, 774-794, 837-847, 854-857, 907-936, 955-957, 975-1125, 1139, 1151, 1190-1195, 1203-1229, 1264-1340, 1344
audrey_start/test_audrey_startup     217     19    91%   65, 130, 384, 420-428, 505-526
—————————————————————-
TOTAL                                689    289    58%

The coverage report command will give you the percentages missing for each script. The coverage report -m command will give you the exact lines missing from the unit test coverage. I checked a few of these lines that it reported, a quick check seems to indicate these are all actual lines of code that were not executed during the unit test run. Pretty useful data for measuring the effectiveness of your unit tests.


Hitler, abortion and the Gospel

October 5th, 2011

What do Hitler, abortion and the Gospel of Jesus Christ have in common?

http://www.180movie.com/

Good stuff. Be patient through the Hitler stuff, he ties it in well.


College Worship Recording Session

September 12th, 2011

My senior year of college A bunch of friends that I played worship with got together in my apartment living room and recorded a demo to send to The Campus Crusade Big Break Conference in Panama City Beach Fl. I had given my life to Christ at that conference 3 years earlier and we were applying to be the worship team for one of the sessions that year.

I have great memories from that afternoon. I still have a copy of the recording and just listened to it. Thought it would be fun to post a copy of it.

Lemme see if I can remember the team that was there:
Radez: Acoustic, Vocals
Andrea: Vocals
Becca: Vocals
Brandon: Electric Guitar
Drew: Drums
Travis: Piano, Vocals
Kevin: Bass
Aaron: Violin
I think that’s everyone…

Here’s what we recorded with a 16 channel mixer, a 4 track recorder and a bunch of college students with instruments in an apartment living room.
01 You Are the One
02 God of Wonders
03 Psalm 61
04 Praise Be
05 Trust in the Lord


Dvorak + Kinesis

September 9th, 2011

I passed a milestone in my Dvorak endeavor yesterday. I had some one looking over my shoulder at what I was doing while I was typing in Dvorak… on a contoured keyboard.

Work bought me a Kinesis Advantage keyboard in May. (Manufacturer’s Page) These are hard enough to get used to in a qwerty layout. It has a native Dvorak mode on it so I made the Kinesis my Dvorak keyboard and the keyboard I was using my qwerty. I had been using both since May. Unplugged the qwerty keyboard the first of September.

This pic is from before I unplugged the qwerty keyboard:


100 Posts / 100,000 miles

September 7th, 2011

I started this blog May 14th 2008.
August 30th 2011 I posted my 100th post which happened to coincide with my car reaching 100,000 miles.

Just a fun fact to share.


100k

August 30th, 2011

Hit 100,000 miles in my jetta today.

20110831-052200.jpg


God is Love

August 29th, 2011

I’ve been in and out of reading Knowing God by J.I. Packer for some time now.
I’ve been enjoying meditating on a passage I read last week:

… the statement “God is Love” means that his love find expressions in everything that he says and does.

The knowledge that this is so for us personally is the supreme comfort for Christians. As believers, we find in the cross of Christ assurance that we, as individuals, are beloved of God; “the Son of God…loved me and gave himself for me” (Gal 2:20). Knowing this, we are able to apply to ourselves the promise that all things work together for good to them that love God and are called according to his purpose (Rom 8:28). Not just some things, note, but all things! Every single thing that happens to us expresses God’s love for us.

Thus, so far as we are concerned, God is love to us – holy, omnipotent love – at every moment and in every event of every day’s life. Even when we cannot see the why and the wherefore of God’s dealings, we know that there is love in and behind them, and so we can rejoice always, even when, humanly speaking, things are going wrong. We know that the true story of our life, when known, will prove to be , as the hymn says, “mercy from first to last” – and we are content.

- J.I. Packer, Knowing God, Pages 122-123

This passage has blessed me as I’ve reflected on the things around me that go “humanly wrong”. Both in my and my family’s life and the life of the people around me. More often than not we do not specifically know, and may never truly know, why a particular event happened in someone’s life. Though, whether we’re glad or scared or frustrated or upset or don’t even care that some whatever has happened, we do know that it happened because our God loves us and is bringing himself glory through his creation.


OpenShift + Django + MySQL

August 17th, 2011

I’ve spent the past 3 years developing two django projects.
Nushus: https://fedorahosted.org/nushus
Loki: https://fedorahosted.org/loki

When Red Hat released openshift I was interested to deploy django on it. I use MySQL with my django apps, mainly because that’s what I know well. The tutorial I was working through used sqlite so I’ve put this together to show how I got MySQL working with django on openshift.

Run this quick start to get your account and domain setup
https://openshift.redhat.com/app/express#quickstart
Then login to the website and open this turoial:
https://www.redhat.com/openshift/kb/kb-e1010-show-me-your-django-getting-django-up-and-running-in-5-minutes
Run the ‘Deploying a Django Application’ section of this tutorial to get a basic django app setup and running. Then you’ll have Django setup but with no admin:

After you get here, continue the tutorial related to the usual code edits needed in your django project to enable the admin. Don’t setup the sqlite database as the tutorial suggests, we’ll get connected to MySQL next.
Next lets setup the database:

testapp git:(master)➤ rhc-ctl-app -e add-mysql-5.1 -a testapp
Password:
Contacting https://openshift.redhat.com
Contacting https://openshift.redhat.com

RESULT:

Mysql 5.1 database added.  Please make note of these credentials:

   Root User: SuperSecretUser
   Root Password: SuperSecretPassword

Connection URL: mysql://127.XXX.XXX.XXXX:3306/

This will create the MySQL instance but not the database.
This forum post suggests the current method to get the database setup: https://www.redhat.com/openshift/forums/express/mysql-db-name
We need to also run syncdb, which the django tuorial shows us how to do. It also shows us how to deploy the admin media. I don’t like how the django tutorial makes us commit static code that’s already deployed. Let’s copy it remotely from the egg that’s already deployed into the remote static dir without commiting it. All this is done via the openshift build hook. I’ve rewritten it a bit in process of testing things so it will look a bit different than the tutorials:

testapp git:(master)➤ cat .openshift/action_hooks/build
#!/bin/bash
# This is a simple build script, place your post-deploy but pre-start commands
# in this script.  This script gets executed directly, so it could be python,
# php, ruby, etc.

# create the database if it doesn't exist
# https://www.redhat.com/openshift/forums/express/mysql-db-name
if ! /usr/bin/mysql -u "$OPENSHIFT_DB_USERNAME" --password="$OPENSHIFT_DB_PASSWORD" -h "$OPENSHIFT_DB_HOST" -e "show tables;" $OPENSHIFT_APP_NAME > /dev/null
then
    /usr/bin/mysqladmin -u "$OPENSHIFT_DB_USERNAME" --password="$OPENSHIFT_DB_PASSWORD" -h "$OPENSHIFT_DB_HOST" create "$OPENSHIFT_APP_NAME"
    echo "Created MySQL database $OPENSHIFT_APP_NAME"
fi

# copy the admin media into place
if [ ! -d "$DIRECTORY" ]; then
    if mkdir $OPENSHIFT_REPO_DIR/wsgi/static/admin
    then
        echo "Created directory $OPENSHIFT_REPO_DIR/wsgi/static/admin"
        echo "Copying admin media into $OPENSHIFT_REPO_DIR/wsgi/static/admin"
        cp -R $OPENSHIFT_APP_DIR/virtenv/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/admin/media/** $OPENSHIFT_REPO_DIR/wsgi/static/admin
    fi
fi

# cd into the project to run django manage.py commands
cd $OPENSHIFT_REPO_DIR/wsgi/testapp

# run syncdb
# https://www.redhat.com/openshift/kb/kb-e1010-show-me-your-django-getting-django-up-and-running-in-5-minutes
echo "Executing './manage.py syncdb --noinput'"
./manage.py syncdb --noinput

This gets us to the login page for the admin:

Now all that’s missing is a user. I toyed with a couple options to get a basic user in. The command line manage.py won’t let you pass a password and I had trouble getting fixtures to load. Though, both of those required sql to verify if the user existed. Settled on a simple management command to make sure we have a user. We have to put it in an app, but we’re going to need an app eventually anyways to make django so more than start. So here’s what I did.
In the project directory run the django startapp command:

testapp/wsgi/testapp git:(master+)➤ ../manage.py startapp myapp

Then add it to the INSTALLED_APPS in your settings file

+     'testapp.myapp',

You have to put the projects name in there, otherwise things won’t work later. I got 500′s trying just to put just ‘myapp’ in the installed apps. This app won’t really do anything for now. It’s just a container for our management command. You can make it into something else later. Next create the directory structure for the command in the myapp directory.

testapp/wsgi/testapp git:(master+)➤ mkdir -p myapp/management/commands
testapp/wsgi/testapp git:(master+)➤ touch myapp/management/__init__.py myapp/management/commands/__init__.py
testapp/wsgi/testapp git:(master+)➤ vim myapp/management/commands/ensuresuperuser.py
testapp/wsgi/testapp git:(master+)➤ tree myapp
myapp
|-- __init__.py
|-- management
|   |-- commands
|   |   |-- ensuresuperuser.py
|   |   `-- __init__.py
|   `-- __init__.py
|-- models.py
|-- tests.py
`-- views.py

2 directories, 7 files

You can see I called my command ensuresuperuser. The command will check if the user exists and create it with a password equal to the user’s username if the user doesn’t exist. Here’s it’s code:

testapp/wsgi/testapp git:(master+)➤ cat myapp/management/commands/ensuresuperuser.py
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User

class Command(BaseCommand):
    args = 'username'
    help = 'make sure a user exists with a password'

    def handle(self, *args, **options):
        try:
            user = User.objects.get(username=args[0])
        except:
            User.objects.create_superuser(args[0], email=args[0]+'@example.com', password=args[0])
            self.stdout.write('user %s created with password %s\n' % (args[0], args[0]))

Last thing to do is to add this command to your build hook so it executes when you push your code, so update your build hook. Here’s the whole contents of mine:

testapp git:(master+)➤ cat .openshift/action_hooks/build
#!/bin/bash
# This is a simple build script, place your post-deploy but pre-start commands
# in this script.  This script gets executed directly, so it could be python,
# php, ruby, etc.

# create the database if it doesn't exist
# https://www.redhat.com/openshift/forums/express/mysql-db-name
if ! /usr/bin/mysql -u "$OPENSHIFT_DB_USERNAME" --password="$OPENSHIFT_DB_PASSWORD" -h "$OPENSHIFT_DB_HOST" -e "show tables;" $OPENSHIFT_APP_NAME > /dev/null
then
    /usr/bin/mysqladmin -u "$OPENSHIFT_DB_USERNAME" --password="$OPENSHIFT_DB_PASSWORD" -h "$OPENSHIFT_DB_HOST" create "$OPENSHIFT_APP_NAME"
    echo "Created MySQL database $OPENSHIFT_APP_NAME"
fi

# copy the admin media into place
if [ ! -d "$DIRECTORY" ]; then
    if mkdir $OPENSHIFT_REPO_DIR/wsgi/static/admin
    then
        echo "Created directory $OPENSHIFT_REPO_DIR/wsgi/static/admin"
        echo "Copying admin media into $OPENSHIFT_REPO_DIR/wsgi/static/admin"
        cp -R $OPENSHIFT_APP_DIR/virtenv/lib/python2.6/site-packages/Django-1.3-py2.6.egg/django/contrib/admin/media/** $OPENSHIFT_REPO_DIR/wsgi/static/admin
    fi
fi

# cd into the project to run django manage.py commands
cd $OPENSHIFT_REPO_DIR/wsgi/testapp

# run syncdb
# https://www.redhat.com/openshift/kb/kb-e1010-show-me-your-django-getting-django-up-and-running-in-5-minutes
echo "Executing './manage.py syncdb --noinput'"
./manage.py syncdb --noinput

# add an admin user
./manage.py ensuresuperuser admin

This time when you commit and push everything you will see it tell you “user admin created with password admin”. Obviously this is really insecure so go ahead and change that password right away. Wouldn’t want your throw away testapp become something it wasn’t intended for.

There you have it, OpenShift + Django + MySQL.
It’s worth noting, If you get a 500 error you need to use the rhc-snapshot command like so:

testapp git:(master+)➤ rhc-snapshot -a testapp
Password:
Contacting https://openshift.redhat.com
Pulling down a snapshot to testapp.tar.gz

This pulls down a tar ball of your running environment and has a logs directory in there that you can look at the apache logs. I’ll second Ian’s suggestion for a rhc-logwatch command. That would be pretty handy.

Next steps for me:
1. How to delete an OpenShift application (i.e. throw away testapp, I’m done with it)
2. Install Nushus in OpenShift!

*** Update ***
I came across another blog post a day later that reference rhc-tail-files. i.e. the watchlog thing I mentioned above is already a feature:

testapp git:(master+)➤ rhc-tail-files -a testapp
Password:
Contacting https://openshift.redhat.com
Attempting to tail files: testapp/logs/*
Use ctl + c to stop

==> testapp/logs/access_log-20110817-000000-EST <==
... snip log files output ...