Author Archive

OpenShift + Django + MySQL

Wednesday, 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 ...

Snake iz ded

Wednesday, August 3rd, 2011

Can’t sleep. All I can think about are the two snakes that have been hiding in the rocks at the lake.

I killed one today with a kayak paddle. It was a small water snake, don’t think it was venomous. It jumped about 3 feet at my wife and son the other day as they were pulling the kayak out of the water, it struck the boat. Luckily they were at the other end of the boat from where it tried to strike. I came across it today sunning itself on a rock and sliced off it’s head. My four year old son told me I had to kill it because snakes are bad.

Other one may have been a cottonmouth but we couldn’t be certain. It gave me a chance to kill it earlier this week but I wasn’t in snake killin’ mode yet.

Next time we’re at the lake the snakes that dare to show themselves won’t stand a chance. I’ll be ready for ‘em. I talk a big game, but really I almost decided to let the one today go. My son talked me back into it. Thanks bud, our dock is a safer place because of you.

Happy Anniversary

Tuesday, August 2nd, 2011

God has blessed my wife and me with 8 years of marriage today!

Gnome 3 two months later

Monday, June 27th, 2011

I’ve been using Fedora 15 and Gnome 3 for a little over  2 months now. I’ve learned a few things that have made my daily workflow a little easier, thought I’d share.

1. the alt key switches the Suspend menu item to “Power Off”
I infrequently need it, but the alternative was to logout and power off from the login screen or to add a gnome-shell-extension.

2. gnome-tweak-tool
There’s a couple settings in there that I was glad to be able to tweak

3. Drag to top of the screen to maximize.
I keep a couple things maximized, It’s nice to just drag the window to the top of the screen and have it maximize.

4. gsettings
I haven’t had too much need for this yet, but understanding it is relevant to writing extensions.

5. gnome-shell-extensions-dock
yum install gnome-shell-extensions-dock
gsettings set org.gnome.shell.extensions.dock position left
alt-f2
r
enter

6. wrote a gnome-shell-extension

Part of my team at work is in Pune, India and our company also pass lots of times around in utc. The Fedora 14 Clock applet that listed what time it was in other timezones was helpful. So I set out last week to put something together in gnome 3 that would serve the same purpose.

In the process I also found some code to add apps to the top panel and decided to post the little bit of code I put together here: https://github.com/radez/gnome-shell-extensions

Here’s what my “clocks” extension looks like. It’s not much but it suits my needs. I need to plug into gsettings as some point so that Pune and UTC arn’t hard coded.

Django, Apache and Semaphores

Tuesday, May 24th, 2011

At work I use Loki to manage my buildbot infrastructure. It’s deployed on apache via mod_wsgi. Recenlty I’ve been having trouble with Apache crashing with one of two single error lines in the logs:

[notice] seg fault or similar nasty error detected in the parent process
or
[emerg] (28)No space left on device: Couldn’t create accept lock

I came across this post and found it very helpful. Start with seeing if there are left over semaphores when you stop apache:

# ipcs -s | grep apache

If that’s the case then first clear them:

# /usr/bin/ipcs -s | grep apache | awk ‘ { print $2 } ‘ | xargs ipcrm sem

Then tell the kernel to allow more semaphores by adding the followings lines to /etc/sysctl.conf

kernel.msgmni = 1024
kernel.sem = 250 256000 32 1024

then run

# sysctl -p

Once I start everything back up this seems to have fixed my issues.

DIY macbook power supply repair

Monday, May 23rd, 2011

image

Not too long ago our power supply for our macbook died. Just wouldn’t charge anymore. Go a new on on eBay for $30. Problem is that one broke this past weekend at the magnetic connection that connects to the laptop. I had the old one still and the connector was still in good shape. Naturally I just took a pair of wirer cutters to both of them. Free fix! Now I have a working power supply and a power supply cord that twice the length of the original one.

Naturally Decaffeinated

Thursday, May 12th, 2011

I’ve decided there’s no such thing as naturally decaffeinated. Since decaffeination is a chemical process that removes caffeine and that doesn’t happen naturally. There’s not a natural process that reduces caffeine, and a man made chemical process can’t happen naturally. So how about we say Low Caffeine or Less Caffeine?

Mercy in the face of punishment

Sunday, May 8th, 2011

My son has been given mercy enough times to know that mercy means not getting punished. This past week in the face of punishment he requested mercy. His request was denied, but it gave me another opportunity to share with him the eternal punishment we deserve for the sin we commit. When Jesus faced punishment for our disobedience He too requested mercy and was denied. In His obedience we were graciously promised mercy when He paid our debt.

Philippians 2:8 And being found in human form, he humbled himself by becoming obedient to the point of death, even death on a cross.

When we are faced with punishment from our Heavenly Father at the end of times Christ will have already received the punishment and paid the debt we owe. There will be no need for us to plead for mercy for those who know Christ as their savior.

Philippians 2 continues:

9 Therefore God has highly exalted him and bestowed on him the name that is above every name, 10 so that at the name of Jesus every knee should bow, in heaven and on earth and under the earth, 11 and every tongue confess that Jesus Christ is Lord, to the glory of God the Father.

Our God that humbled Himself to a humiliating and excruciating death that we could live eternally in His presence.

The Inteligence of a one year old

Friday, May 6th, 2011

My one year old son was sitting on my lap this morning. He was humming and singing nothing in particular. My wife came over and asked him if he would like to sing The Wheels on the Bus. He considered this for half a second and responded with his favorite new word. “No.” Next she asked him if he’d like to sing The Intsey Weantsy Spider. “No.” Thinking it would be a good laugh to have him say no to something all kids always want she continues with sugar. “Would you like some cake and ice cream?” After careful consideration, he leans forward, looks her directly in the eyes and in a drawn out emphatic delivery responds “Pweeeese”.

Gnome 3 on Fedora 15

Saturday, April 9th, 2011

Went ahead an updated to Fedora 15 this evening.
Though Gnome 3 will take some time to get used to, I think I’ll like it over time.