A better Jira init.d script for Redhat/CentOS

I wrote a bit better init.d script for Jira for Redhat/CentOS

The first thing you want to do is create a sysconfig file. Below is the filename

/etc/sysconfig/jira

The file has the following contents in it

#
# The user Jira runs as
#
JIRA_USER=jira

#
# The home directory of Jira
#
JIRA_HOME=/opt/jira/current

Now create the init.d script

/etc/init.d/jira

It has the following contents in it.

#!/bin/sh
#
# JIRA startup script
#
# chkconfig: 2345 80 05
# description: JIRA

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/jira ]; then
    . /etc/sysconfig/jira
fi

prog=jira
RETVAL=0

start() {
        echo -n $"Starting $prog: "
        /bin/su -m $JIRA_USER -c "cd $JIRA_HOME/logs && $JIRA_HOME/bin/startup.sh &> /dev/null"
        RETVAL=$?
        if [ $RETVAL = 0 ]
        then
                echo $! > /var/run/jira.pid
                echo_success
        else
                echo_failure
        fi

        echo

        return $RETVAL
}

stop() {
        echo -n $"Stopping $prog: "
        /bin/su -m $JIRA_USER -c "$JIRA_HOME/bin/shutdown.sh &> /dev/null"
        RETVAL=$?
        if [ $RETVAL = 0 ]
        then
                rm -f /var/run/jira.pid
                echo_success
        else
                echo_failure
        fi
        echo

        return $RETVAL
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                sleep 5
                start
                ;;
        *)
                echo $"Usage: /etc/init.d/$prog {start|restart|stop}"
                exit 1
                ;;
esac

exit $RETVAL

Now make permissions correct

chmod +x /etc/init.d/jira

Now you can chkconfig it

chkconfig jira on

This will make it look a bit more Redhat/CentOS like.

Init.d script for puppet-dashboard

In the #puppet IRC channel on freenode a user was asking if anyone knew of a init.d script for redhat/fedora for puppet-dashboard. I have a blog post about installing puppet-dashboard on Redhat/CentOS and I don’t think there is any init.d script out there. So time to write one

The first thing you will create is the following file

/etc/sysconfig/puppet-dashboard

This is a simple file with the following in it

#
# path to where you installed puppet dashboard
#
DASHBOARD_HOME=/opt/puppet-dashboard

You probably need to change the DASHBOARD_HOME variable to match what you have. Its the root of the project.

Now for the init.d script. Create the file called

/etc/init.d/puppet-dashboard

With the following contents in it.

#!/bin/bash
#
# Init script for puppet-dashboard
#
# chkconfig: - 85 15
# description: Init script for puppet-dashboard

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/puppet-dashboard ]; then
    . /etc/sysconfig/puppet-dashboard
fi

prog=puppet-dashboard
RETVAL=0

start() {
        echo -n $"Starting $prog: "
        /usr/bin/ruby ${DASHBOARD_HOME}/script/server >/dev/null 2>&1 &
        RETVAL=$?
        if [ $RETVAL = 0 ]
        then
            echo $! > /var/run/puppet-dashboard.pid
            echo_success
        else
            echo_failure
        fi 

        echo

        return $RETVAL
}
stop() {
        echo -n $"Stopping $prog: "
        killproc puppet-dashboard
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f /var/run/puppet-dashboard.pid
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo $"Usage: $prog {start|stop|restart}"
        exit 1
esac

exit $RETVAL

This might not be perfect but it works nicely

SSH Trick

To start off with.. I know you can do this in DNS using a search parameter but I don’t want to do that in my envirnoment.

Sometimes you are working with a hostname that is long due to the domain name. This is the case where I am currently working, the domain is theopenskyproject.com. So I did the following and added into my ~/.bashrc

function ssh() { /usr/bin/ssh $1.theopenskyproject.com; }

You can now do the following

ssh node1
ssh user@node1

Right now its pretty simple. Flags won’t work with ssh. If you want you can make it more shorthand by calling the function s

Google Apps List Shared Contacts

I’ll be the first to call out Google that their gdata python library for connecting into the Google Apps API is the worst.

I wanted to grab all the shared contacts from our domain and it was a giant in the ass. Here is the code I ended up with


import gdata.contacts.client

contact_list = gdata.contacts.client.ContactsClient()
contact_list.client_login(email="user@domain.com",
                                password="password",
                                source='comany-app-1',
                                account_type='HOSTED')
feed_url = contact_list.GetFeedUri(contact_list="domain.com", projection='full')

while True:
    feed = contact_list.get_feed(
                                uri=feed_url,
                                auth_token=None,
                                desired_class=gdata.contacts.data.ContactsFeed)

    for entry in feed.entry:
        print entry.title.text

    next_link = feed.GetNextLink()
    if next_link is None:
        break

    feed_url = next_link.href

The email you use needs to have admin rights over your domain in Google Apps.

Django: Custom Decorator with an Argument

Sometimes you want to be able to create a decorator for functions in Django but have the ability to pass in an argument into the decorator. I came across this when I wanted to switch from the require_login decorator to check if a user was in a certain group to see the function.

So the first thing I did was create a new directory in my project root called decorators and put a blank __init__.py file there. My I cated an auth.py file with the following contents.

from functools import wraps

from django.contrib.auth.models import Group
from django.http import Http404

def group_required(groups=[]):    
    def decorator(func):
        def inner_decorator(request,*args, **kwargs):
            for group in groups:
                try:
                    if Group.objects.get(name=group) in request.user.groups.all():
                        return func(request, *args, **kwargs)
                except:
                    pass

            raise Http404()

        return wraps(func)(inner_decorator)

    return decorator

So we can use it like this in our project


from decorators.auth import group_required

@group_required(["admins"])
def show_index(request):
    ....

I decided to make it a list being passed in. The main reason was to make it was to pass in multiple groups that you might want to allow to be allowed in.

My version doesn’t do much error checking.. if you want a more updated version of this function checkout my githib project I’ve started to put all my custom decorators up and online

http://github.com/mzupan/django-decorators

What Rollout will be?

I have been debating just helping with fabric or writing my own app for a week now and I just think what I need and want fabric just isn’t and too much work to get it to the way I want it to be.

So here are some of the things I want Rollout to be.

  1. Be able to run in console
  2. Be able to tie the Rollout API into your own python webapp
  3. Rollout output should be multiformat (xml/json)
  4. Should be threaded
  5. Should have a run_first() and run_last() method
  6. Tie in git/svn?

Again if you want to watch the project it is http://github.com/mzupan/rollout

Reason #2 on why Django is great

The decorators that Django has are a great time saver. There are a lot of methods in your views where you only want logged in users to see. So you can use a decorator before the function to check if they are logged in or not.

from django.contrib.auth.decorators import login_required

@login_required
def my_view(request):
    ....

So learn to use these time savers in your project.

Nginx proxy timeout fix

This is something that is an easy fix. Nginx is a great web server not only for your primary site but for a proxy as well since it is made to serve a lot of requests very fast.

So it is as simple as this


location / {
  proxy_pass https://staging;
  proxy_read_timeout 500;
  proxy_next_upstream error;
  break;
}

The key lines are proxy_read_timeout and proxy_next_upstream.

Rollout has been designed

I’m a big fan of fabric, a python module to make deployments easy. It is still very new but has some great features and some major short comings I don’t think the authors thought of before they designed it.

The major shortcoming is a lack of parallel deployments. Fabric works great on 1 or 2 hosts you need to deploy on but when you have more then that for a large application it is painful. There is a patch for parallel deployments and it works but it “breaks” some features of fabric. The main one is the @runs_once.

So I am going to try to build a python module to better handle deployments in a parallel fashion. I have decided to model my module after fabric since I’m very use to it and I think their model works.

I started a GitHub project for it but don’t have any code in there yet.

http://github.com/mzupan/rollout

If you are interested please keep an eye on the project. I hope to make it functional soon.

Remote Editing with Eclipse

I was doing some Django work trying to get PayPal WPP to work with my application and it was stuck behind your basic LinkSys wifi router. Now you can just go in and forward the ports, edit PalPal configs and bla bla bla.

That is no fun. So I found a nice little plugin for eclipse that handles remote editing over SFTP. So now I can do all my remote testing/development via SFTP and not have to make all these changes.

So do the following, open up your install manager.

Help -> Install New Software

Add the following URL to the box with Work with

http://download.eclipse.org/dsdp/tm/updates/

Now select the following item

RSE_Runtime

It might prompt you to install a few dependencies, just install them. It will prompt you to restart eclipse also.

Once it is restarted we need to create a connection

Window -> Open Perspective -> Other

Then select

Remote System Explorer

Then you will see a Remote Systems tab that has appeared and you can right click in that tab and create a new connection. Then you are good to edit remotely.

« Previous PageNext Page »