Tag Archives: init

Create init script in CentOS 6

The purpose of this post is to document how to create init script in CentOS 6 to be used with the usual service management commands such as service and chkconfig.

Introduction

After being somewhat dissatisfied with the service script provided by GlassFish, I decided to learn how to create my own service script to start, stop, and view the status of non-packaged applications.

Learn Shell Scripting

I began by looking at other service scripts that has been already provided by CentOS such as /etc/init.d/httpd and /etc/init.d/iptables for ideas.

To help understand the scripts, I had to start learning shell scripting.  A very good tutorial can be found here.

Writing the script

The skeleton script

There is a file inside CentOS that explains a bit about how to write init scripts.  The path to the file is /usr/share/doc/initscripts-*/sysvinitfiles.  You can open this file in a text editor, and have a read.

Included in this file is a base outline of an init script that we can base our script on.  The following is the content of the outline:

#!/bin/bash
#
#       /etc/rc.d/init.d/<servicename>
#
#       <description of the *service*>
#       <any general comments about this init script>
#
# <tags -- see below for tag definitions.  *Every line* from the top
#  of the file to the end of the tags section must begin with a #
#  character.  After the tags section, there should be a blank line.
#  This keeps normal comments in the rest of the file from being
#  mistaken for tags, should they happen to fit the pattern.>

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

<define any local shell functions used by the code that follows>

start() {
        echo -n "Starting <servicename>: "
        <start daemons, perhaps with the daemon function>
        touch /var/lock/subsys/<servicename>
        return <return code of starting daemon>
}

stop() {
        echo -n "Shutting down <servicename>: "
        <stop daemons, perhaps with the killproc function>
        rm -f /var/lock/subsys/<servicename>
        return <return code of stopping daemon>
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        <report the status of the daemons in free-form format,
        perhaps with the status function>
        ;;
    restart)
        stop
        start
        ;;
    reload)
        <cause the service configuration to be reread, either with
        kill -HUP or by restarting the daemons, in a manner similar
        to restart above>
        ;;
    condrestart)
        <Restarts the servce if it is already running. For example:>
        [ -f /var/lock/subsys/<service> ] && restart || :
    probe)
        <optional.  If it exists, then it should determine whether
        or not the service needs to be restarted or reloaded (or
        whatever) in order to activate any changes in the configuration
        scripts.  It should print out a list of commands to give to
        $0; see the description under the probe tag below.>
        ;;
    *)
        echo "Usage: <servicename> {start|stop|status|reload|restart[|probe]"
        exit 1
        ;;
esac
exit $?

Create init script by modifying the skeleton script

Using the skeleton script as a base, and comparing it with other established init scripts, I have come up with the following for GlassFish 4:

#!/bin/bash
#
# glassfish4    GlassFish Server Open Source Edition 4.0
#
# chkconfig: 345 70 30
# description: GlassFish Server is a Java EE Application Server Platform
# processname: glassfish4

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

RETVAL=0
prog="glassfish4"
LOCKFILE=/var/lock/subsys/$prog

# Declare variables for GlassFish Server
GLASSFISH_DIR=/home/gfish/glassfish4
GLASSFISH_USER=gfish
ASADMIN=$GLASSFISH_DIR/bin/asadmin
DOMAIN=domain1

start() {
        echo -n "Starting $prog: "
        daemon --user $GLASSFISH_USER $ASADMIN start-domain $DOMAIN
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch $LOCKFILE
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $prog: "
        $ASADMIN stop-domain domain1 && success || failure
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
        echo
        return $RETVAL
}

status() {
        echo -n "Checking $prog status: "
        $ASADMIN list-domains | grep $DOMAIN
        RETVAL=$?
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $prog {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Using the script

Add the script to chkconfig

The script is placed inside the /etc/init.d/ directory, and given the name glassfish4.

Then, the script is added to the list using the chkconfig command.

[root@server ~]# chkconfig --add glassfish4
[root@server ~]# chkconfig --list glassfish4
glassfish4      0:off   1:off   2:off   3:on    4:on    5:on    6:off

Use the start operand

[root@server ~]# service glassfish4 start
Starting glassfish4: Waiting for domain1 to start .........................
Successfully started the domain : domain1
domain  Location: /home/gfish/glassfish4/glassfish/domains/domain1
Log File: /home/gfish/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.
                                                           [  OK  ]

Use the stop operand

[root@server ~]# service glassfish4 stop
Shutting down glassfish4: Waiting for the domain to stop ......
Command stop-domain executed successfully.
                                                           [  OK  ]

Use the restart operand

[root@server ~]# service glassfish4 restart
Shutting down glassfish4: Waiting for the domain to stop ..
Command stop-domain executed successfully.
                                                           [  OK  ]
Starting glassfish4: Waiting for domain1 to start ......................
Successfully started the domain : domain1
domain  Location: /home/gfish/glassfish4/glassfish/domains/domain1
Log File: /home/gfish/glassfish4/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.
                                                           [  OK  ]

Use the status operand

[root@server ~]# service glassfish4 status
Checking glassfish4 status: domain1 running

Use any other operands

[root@server ~]# service glassfish4 lalala
Usage: glassfish4 {start|stop|status|restart}

Start GlassFish 4 automatically on CentOS 6

Introduction

The purpose of this post is to document how to start GlassFish 4 automatically whenever the server it is installed in reboots.

The VPS that is hosting my Oracle APEX installation rebooted without warning the other day (as should be expected of cheap services), which required me to personally SSH into the server to restart GlassFish.

The prospect of having to manually restart GlassFish every time the server reboots does not look appealing to me.  I need to find a way to make GlassFish start automatically on boot.

Using GlassFish create-service command

Run the command

The GlassFish 4 Administration Guide Page 3-13 clearly recommends the use of the built-in command called create-service in order to automatically start GlassFish when the server boots up.

Let’s try and see it in action.

[root@server ~]# $GLASSFISH_DIR/bin/asadmin
Use "exit" to exit and "help" for online help.
asadmin> create-service
Found the Linux Service and successfully uninstalled it.
The Service was created successfully. Here are the details:
Name of the service:domain1
Type of the service:Domain
Configuration location of the service:/etc/init.d/GlassFish_domain1
User account that will run the service: root
You have created the service but you need to start it yourself.  Here are the most typical Linux commands of interest:

* /etc/init.d/GlassFish_domain1 start
* /etc/init.d/GlassFish_domain1 stop
* /etc/init.d/GlassFish_domain1 restart

For your convenience this message has also been saved to this file: $GLASSFISH_DIR/glassfish/domains/domain1/PlatformServices.log
Command create-service executed successfully.
asadmin> exit
Command multimode executed successfully.

Attempt to start GlassFish service

It seemed that the command completed successfully.  Now let’s try to start the service.

[root@server ~]# /etc/init.d/GlassFish_domain1 start
[root@server ~]# /etc/init.d/GlassFish_domain1: line 54: $GLASSFISH_DIR/glassfish/lib/nadmin: Permission denied

Something is wrong in the script somewhere.  Let’s examine the contents of the init script created by the create-service command.

[root@server ~]# vi /etc/init.d/GlassFish_domain1

Review lines 50 to 64:

ASADMIN="$GLASSFISH_DIR/glassfish/lib/nadmin"

case "$1" in
start)
    $ASADMIN start-domain    --domaindir $GLASSFISH_DIR/glassfish/domains  domain1 &
    ;;
stop)
    $ASADMIN stop-domain   --domaindir /$GLASSFISH_DIR/glassfish/domains  domain1 &
    ;;
restart)
    $ASADMIN restart-domain   --domaindir $GLASSFISH_DIR/glassfish/domains  domain1 &
    ;;
*)
    echo "usage: $0 (start|stop|restart|help)"
esac

The path to the asadmin command is wrongly set in the script.  The correct path should be $GLASSFISH_DIR/bin/asadmin.  Changing this to the correct path should rectify the error.

Modify the script

Change line 50 as follows:

ASADMIN="$GLASSFISH_DIR/bin/asadmin"

Start GlassFish service

The GlassFish server can now be started using the modified script.

[root@server ~]# service GlassFish_domain1 start
[root@server ~]# Waiting for domain1 to start .........................
Successfully started the domain : domain1
domain  Location: $GLASSFISH_DIR/glassfish/domains/domain1
Log File: $GLASSFISH_DIR/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

Restart GlassFish service

The GlassFish server can also be restarted by the script.

[root@server ~]# service GlassFish_domain1 restart
[root@server ~]# Successfully restarted the domain
Command restart-domain executed successfully.

Stop GlassFish service

Last but not least, the script can stop the GlassFish domain.

[root@server ~]# service GlassFish_domain1 stop
[root@server ~]# Waiting for the domain to stop
Command stop-domain executed successfully.

Start GlassFish 4 automatically on reboot

In addition to creating the init.d script, the asadmin create-service command also creates symbolic links inside the rc*.d folders, which makes GlassFish start automatically on runlevels 3,4 and 5.

Problems with the script

Although the script created by the asadmin create-service command is functional, I am not quite satisfied with it for the following reasons:

No chkconfig support

Other scripts in the init.d folder can be managed via the chkconfig command.  You can set which runlevels you want to run your service in using this command.  However, the script created using the asadmin create-service command is not compatible with chkconfig.

[root@server ~]# chkconfig GlassFish_domain1 --list
service GlassFish_domain1 does not support chkconfig

No status checking

Other scripts in the init.d folder use the status operand to check the running status of the service.  For instance, for the Apache web server:

[hnizam@server ~]$ sudo service httpd status
httpd (pid  13365) is running...

Unfortunately, the script provided by the asadmin create-service command does not include the definition for the status operand.

[root@server ~]# service GlassFish_domain1 status
usage: /etc/init.d/GlassFish_domain1 (start|stop|restart|help)

GlassFish runs under root user

Finally, the way the script created by the asadmin create-service command is written makes GlassFish run under the root user ID.

If you installed GlassFish under a non-root non-privileged user, and wants the GlassFish process to run under this user ID, the script will not do this for you.

Conclusion

To start GlassFish 4 automatically every time the server boots up, you can use the asadmin create-service command.  However, on Centos 6 at least, the script created by the command will not work out of the box.  Some modifications need to be done on the script before it will work as intended.