Author Archives: thtieig

Whatsapp to command your Raspberry Pi and Nagios monitoring

Do you want to command your Raspberry Pi via Whatsapp and have this system monitored and brought up by Nagios in case it dies?

Follow this guide! šŸ™‚

Requirements:

  • Spare SIM card (number will be used by your Raspberry Pi)
  • A phone to keep the SIM card on during the registration process only
  • A Raspberry Pi (Debian 8 recommended)
  • Nagios

Let’s do it!

Step 1: Put your SIM in the phone and make sure the SIM can receive text messages (no data is required)

Step 2: Install/configure your Raspberry Pi

 

Installation

Yuwsup

To make all this magic happening,Ā we’re going to use Yowsup

Here some easy steps to install on Raspian: (you can use also pip install yowsup2):

$ sudo apt-get install git python-dev libncurses5-dev
$ git clone git://github.com/tgalal/yowsup.git
$ cd yowsup
$ sudo python setup.py install

Once installed, you need to register your phone number, extract the password and use it to configure the following scripts.

To register, create a file calledĀ mydetails and add the following (replace country code and phone number accordingly):

cc=44
phone=447711111123

After that, run this:

python yowsup-cli registration --config mydetails --requestcode sms

You should receive a text on your phone with a 6 digits code (xxx-xxx format). Use the following command to get the password:

python yowsup-cli registration --config mydetails --register xxx-xxx

After a little while, you should see some output like this:

status: ok

kind: free

pw: 9BkIpOaLpCk1LxuQIK8Vrt6XwNkj=

price: 0.79

price_expiration: 1434674994

currency: GBP

cost: 0.79

expiration: 1463544490

login: 4425784541474

type: new

Grab theĀ pwĀ bit and add append to your mydetails file:

cc=44
phone=447711111123
password=9BkIpOaLpCk1LxuQIK8Vrt6XwNkj=

Now you can test using the below bash script (demo.sh):

#!/bin/bash
echo -e "\e[31m"
echo 'Once you get the prompt just use /L to go online'
echo 'After that you can send a message in this way:'
echo '/message send 449988776655 "Hello from the Raspberry Pi!"'
echo -e "\e[0m\n"

yowsup-cli demos --yowsup --config mydetails

All should (hopefully) work! šŸ™‚

Python scripts for yowsup

The following scripts and configurations are based on the following:

  • the user “piuser” is the one who will run the main scripts
  • scripts are stored into /home/piuser/WhatsappOnPi/scripts
  • the user “nagios” will need some extra privileges to run some scripts

 

InĀ /home/piuser/WhatsappOnPi/scriptsĀ create the following scripts:

1) whatsapp.py

This script is the one that keeps layer.py script up and running.

from yowsup.stacks                             import YowStackBuilder
from yowsup.common                             import YowConstants
from yowsup.layers                             import YowLayerEvent
from layer                                     import EchoLayer
from yowsup.layers.auth                        import YowAuthenticationProtocolLayer
from yowsup.layers.coder                       import YowCoderLayer
from yowsup.layers.network                     import YowNetworkLayer
from yowsup.env                                import YowsupEnv
from mysettings import *

#Uncomment to log
#import logging
#logging.basicConfig(level=logging.DEBUG)

CREDENTIALS = (phone, password)

if __name__==  "__main__":
    stackBuilder = YowStackBuilder()

    stack = stackBuilder\
        .pushDefaultLayers(True)\
        .push(EchoLayer)\
        .build()

    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS)       #setting credentials
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))          #sending the connect signal
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0])           #whatsapp server address
    stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
    stack.setProp(YowCoderLayer.PROP_RESOURCE, YowsupEnv.getCurrent().getResource())  #info about us as WhatsApp client

    stack.loop( timeout = 0.5, discrete = 0.5 )
2) layer.py

This script is the main one that you need to customise as you’d like:

# -*- coding: utf-8 -*-
import os, subprocess, time, re
from yowsup.layers                                     import YowLayer
from yowsup.layers.interface                           import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_messages.protocolentities  import TextMessageProtocolEntity
from yowsup.layers.protocol_receipts.protocolentities  import OutgoingReceiptProtocolEntity
from yowsup.layers.protocol_acks.protocolentities      import OutgoingAckProtocolEntity
from mysettings	import *

ap = set(allowedPersons)

# Message on Start Up
startcommand='yowsup-cli demos -l %s:%s -s %s "*[INFO] System Started*: `uptime`" 2>&1 > /dev/null ' % (phone, password, destphone)
subprocess.call(startcommand , shell=True)



def sendMessage(self, messageProtocolEntity, msg):
   outgoingMessageProtocolEntity = TextMessageProtocolEntity(
      ''+msg+'',
      to = messageProtocolEntity.getFrom())
   self.toLower(outgoingMessageProtocolEntity)

class EchoLayer(YowInterfaceLayer):
    @ProtocolEntityCallback("message")
    def onMessage(self, messageProtocolEntity):
        #send receipt otherwise we keep receiving the same message over and over

        if True:
            receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom(), 'read', messageProtocolEntity.getParticipant())
            self.toLower(receipt)

        if messageProtocolEntity.getFrom(False) in ap:
             message_body = messageProtocolEntity.getBody().lower().strip(' \t\r\n\0')
             #print (message_body)

             # Local System Control
             if 'help' in (message_body):
		msg='Commands available:\nrestart <device>\nuptime\ndf\nlast\nrouter'
                sendMessage(self, messageProtocolEntity, msg)
	     #elif 'reboot' in (message_body):
             #   result=subprocess.check_output(["sudo", "reboot"])
             #   msg='reboot: '+result+''
             #   sendMessage(self, messageProtocolEntity, msg)
             elif 'uptime' in (message_body):
                result=subprocess.check_output(["uptime"])
                msg=''+result+''
                sendMessage(self, messageProtocolEntity, msg)
             elif 'df' in (message_body):
                result=subprocess.check_output(["df", "-h"])
                msg=''+result+''
                sendMessage(self, messageProtocolEntity, msg)
             elif 'last' in (message_body):
                result=subprocess.check_output(["last"])
                msg=''+result+''
                sendMessage(self, messageProtocolEntity, msg)
             elif 'router' in (message_body):
                result=subprocess.check_output(["/usr/lib/nagios/plugins/check_router_speed"])
                msg=''+result+''
                sendMessage(self, messageProtocolEntity, msg)


             # Reboots Control
             # ---------------
             # this uses a wrapper called 'restart_device'
             # bash script with 'case' that issues specific commands over ssh
             # to restart different hosts

             elif message_body.startswith('restart'):
                cmd = message_body.split('restart', 1)[1]
                if 'skyhub' in (cmd):
		   result=subprocess.check_output(["sudo", "restart_device", "router1"])
                   msg=''+result+''
                   sendMessage(self, messageProtocolEntity, msg)
                elif 'asus8uk' in (cmd):
		   result=subprocess.check_output(["sudo", "restart_device", "router2"])
                   msg=''+result+''
                   sendMessage(self, messageProtocolEntity, msg)
		elif 'raspberrino' in (cmd):
		   result=subprocess.check_output(["sudo", "restart_device", "raspberrypi"])
                   msg=''+result+''
                   sendMessage(self, messageProtocolEntity, msg)
		elif 'raspbxino' in (cmd):
                   result=subprocess.check_output(["sudo", "restart_device", "pbx"])
                   msg=''+result+''
                   sendMessage(self, messageProtocolEntity, msg)
                else:
                   msg='Usage: restart (router1|router2|raspberrypi|pbx)'
                   sendMessage(self, messageProtocolEntity, msg)

             else:
                msg='Command '+messageProtocolEntity.getBody()+' unknown.\nUse: help'
                sendMessage(self, messageProtocolEntity, msg)

        else:
	     # Report
             msg='** Alert**  \nSender: '+messageProtocolEntity.getFrom()+' '+messageProtocolEntity.getBody()+''
             outgoingMessageProtocolEntity = TextMessageProtocolEntity(
                ''+msg+'',
                to = '%[email protected]' % destphone )
             self.toLower(outgoingMessageProtocolEntity)

             # Reply
             msg='No'
             sendMessage(self, messageProtocolEntity, msg)

    @ProtocolEntityCallback("receipt")
    def onReceipt(self, entity):
        ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", entity.getType(), entity.getFrom())
        self.toLower(ack)
3) mysettings.py

This is included in both scripts and it needs to be updated accordingly:

#################################################################################################
# TO EDIT - add your phone number and password
#
phone="447711111123"
password="9BkIpOaLpCk1LxuQIK8Vrt6XwNkj="
destphone="<your_personal_number>"
#allowedPersons=['<your_personal_number>','<another_number_allowed_to_talk_with_your_pi>']
allowedPersons=['<your_personal_number>']
#
#################################################################################################

 

Now let’s create a wrapper to start the script: Ā /usr/local/bin/whatsapp_start

#!/bin/bash

# kill process if running
for PID in $(ps aux | grep -i "[p]ython.*whatsapp" | awk '{print $2}') ; do
   kill -9 $PID > /dev/null 2>&1
done

# restart process
python /home/piuser/WhatsappOnPi/scripts/whatsapp.py &

 

And now let’s append this into /etc/rc.local:

echo "Starting whatsapp service"
su - piuser -c /usr/local/bin/whatsapp_start

Done!
Every time we reboot the server, the script will start!

 

But… what happens if the script dies or something goes wrong?

Answer: Nagios!

Create custom plugin script for Nagios and save it inĀ /usr/lib/nagios/plugins/check_whatsapp

NOTE: Make sure to follow the notes in this script to proper setup visudo

#!/bin/bash

####################################################################################
# user 'nagios' needs to be allowed to run 'netstat' using sudo
# and /usr/local/bin/whatsapp_start to run as 'piuser'
#
# Required lines in visudo:
#
#    Cmnd_Alias WHATSAPP_CMD = /bin/su - piuser -c /usr/local/bin/whatsapp_start
#    nagios ALL=(ALL) NOPASSWD:/bin/netstat,WHATSAPP_CMD
#
####################################################################################

sudo netstat -pant | grep -q "ESTABLISHED.*python"

if [ $? -eq 0 ] ; then
   echo "OK- Whatsapp is up and running"
   exit 0
else
   echo "CRITICAL- Whatsapp service stopped or not connected. Attempting restart."
   sudo su - piuser -c /usr/local/bin/whatsapp_start
   exit 2
fi

 

Now let’s enable this script inĀ /etc/nagios/nrpe_local.cfg:

command[check_whatsapp]=/usr/lib/nagios/plugins/check_whatsapp

 

On the Nagios SERVER, let’s add the new service.
Following my current setup mentioned here, I’m going to add the following inĀ /etc/nagios3/conf.d/hostgroups_services.cfg

#######################################################################################
# Check Whatsapp Service
define hostgroup {
        hostgroup_name  whatsapp-servers
                alias           whatsapp servers
        }
define service {
        hostgroup_name                  whatsapp-servers
        service_description             whatsapp service
	normal_check_interval           5
        retry_check_interval            2
        check_command                   check_nrpe_1arg!check_whatsapp
        use                             generic-service
}

#######################################################################################

When the service is configured, we need to append this service on the host where we want the check to be executed and verified (config inĀ /etc/nagios3/conf.d/hosts.cfgĀ – eg:)

        hostgroups      allservers,ssh-servers,http-servers,whatsapp-servers

 

A couple of restarts/reloads (nagios client and nagios server), and the check should be now visible in the web interface! šŸ™‚


NOTE: You might seeĀ Waiting for this message. This may take a while.” on your Whatsapp while trying to talk with your Pi. And you can wait as much as you like, but it won’t get fixed by itself.

So… how make things working again?
What I’ve done to fix it is:

  • stopping nagios3 (setup to try to restart Whatsapp script if down)
  • kill the whatsapp python script running
  • use the above demo.sh script to send/receive some manual messages
  • if you can chat (send/receive correctly), you can now stop demo.sh script and start again your whatsapp python script

This always fixed this issue for me šŸ™‚


Apologies for the typos and mistakes. This has been published more as a note for me thanĀ a proper how-to

Source:Ā http://www.techradar.com/how-to/computing/how-to-control-a-raspberry-pi-using-whatsapp-1315610/2

Many thanks to Paul for the initial python scripts templates šŸ™‚

Physically restart Sky router via Raspberry Pi

I have a Sky Hub router, theĀ SR102 (black).Ā Previously I had the white version as well.
Nice routers, pretty stable, but badly locked. You can change the SID of your wifi, change the password… not either sure if you can do a proper port forwarding. So… perfect for my mum,Ā but a pain for whoever wants a little bit of extra control.

I had already an ASUS RT-N16 with DD-WRT firmwareĀ so I used the DMZ function on the Sky router to have some sort of “link” of the public IP of my broadband directly on the WAN interface of the router. In this way it’s like that is my ASUS router that does the connection and I can play as freely as I want, without caring much about the Sky router.

However, it happens that sometimes you need to give a full reboot to the main Sky router. And maybe do this automatically or via command line/script. And here it’s when things are getting more complicated.

The Sky Hub router allows you to reboot it via HTTP. Using the DMZ anyway will bypass the router itself and forward all the requests to the ASUS router. Also, I have never liked the idea to expose my router management page to the Internet, but I rather prefer to connect via SSH on a Raspberry Pi and issue commands from the terminal (telnet/ssh).

So, beside my multiple attempts to find a way to curl the button on the page, I had to find an alternative way to makes this happen. Of course, it didn’t help either to call the Sky Helpline asking if there was a remote possibility to have telnet enabled.

After a bit of talks on Facebook with some friends, here the solution:Ā Remote Controlled Sockets with Pi-mote

Yes. If I can’t reboot fromĀ inside, let’s to that fromĀ outside!

The process was pretty straight forward.

First of all, I had to turn off my Raspberry Pi, and plug theĀ “little green piece of board” as mentioned in here

After that, I’ve turned the pi on again, and installed the required packages. Happily I found that there is now the python library available forĀ energenie, so I have installed them as well, making my life easier šŸ™‚

apt-get install python-rpi.gpio python-pip
pip install energenie

Once done, I have created these two basic script and I have run one a time, to configure the socket plugs.

Make sure to plug the ONE SOCKET PLUG A TIMEĀ and run the relative script.

You can find more information in the previous PDF, but these sockets learn who they are based on which commands they are receiving during the learning mode (enabling keeping the green button pressed for about 5 seconds when switched off). So if you run the first script with both plugs connected and in learning mode, they will do exactly the same, and unless you want to control two sockets at the same time, better to follow the instructions šŸ™‚

Script to configure the first socket:

from energenie import switch_on, switch_off
from time import sleep

# turn the first plug socket ON and then OFF
switch_on(1)
sleep(5)
switch_off(1)

 

Script to configure the second socket:

from energenie import switch_on, switch_off
from time import sleep

# turn the second plug socket ON and then OFF
switch_on(2)
sleep(5)
switch_off(2)

 

And now, my simple script to make… “the magic”: plugs.py

from energenie import switch_on, switch_off
from time import sleep
import sys

if len(sys.argv) == 1:
    print "Use:\n# python plug.py <plug_ID> <ON/OFF>\ne.g. # python plug.py 1 ON"
    exit(1)

else:
    plug = sys.argv[1]
    status = sys.argv[2]

if status.lower() == 'on':
   switch_on(int(plug))
else:
   switch_off(int(plug))

You can use this script to control any sockets (up to 4 – hardware limitation).

And here a bash wrapper (I’m not really good in python sorry) that calls plugs.py and restart the router:Ā restart_sky_router

#!/bin/bash

# This script requires plug.py script

if [ "$EUID" -ne 0 ]
  then echo "Please run as root or use 'sudo'"
  exit
fi

echo "Switching OFF and then ON the physical socket"


# Uses ENERGENIE Radio controlled Sockets
python plug.py 1 off
sleep 10
python plug.py 1 on

 

Now, I can have my Nagios system to check for the speed as documented here and eventually issueĀ restart_sky_router script to see if it fixes the issue. Or simply be able to have a command to integrate in your scripts!

 

Check Sky Hub speed script

Bash script that extract the router speed.

#!/bin/bash

# Broadband Speed within limits Download 14000 and Upload 750

ROUTER=<router_ip>
USER=<router_username>
PASS=<router_password>
# Download Link speed
DL=14000
# Upload Link speed
UL=750

SPEED=($(wget -qO- http://$ROUTER/sky_router_status.html --user=$USER --password=$PASS | awk -F "'" '$0 ~ /Modemstat\[0\]/  {print $2, $4}'))

if [[ ${SPEED[0]} -lt $DL || ${SPEED[1]} -lt $UL ]] ; then
  exit 2
else
  echo "Broadband Speed within limits Download ${SPEED[0]} and Upload ${SPEED[1]}"
  exit 0
fi

 

This can be integrated in Nagios to send an alert if the speed drops.

GlusterFS

Example of GlusterFS configuration on 2 servers with Block Storage attached.

This setup is suggested for TESTING purposes only. In a production environment please verify performances.

Create a separate network and map IP/servers' names in /etc/hosts
Append to /etc/hosts
# GlusterFS
192.168.3.5     gfs01
192.168.3.6     gfs02

>> On BOTH nodes:

yum update
wget -P /etc/yum.repos.d http://download.gluster.org/pub/gluster/glusterfs/LATEST/CentOS/glusterfs-epel.repo
yum -y install parted lvm2 xfsprogs glusterfs glusterfs-fuse glusterfs-server
grep ^exclude /etc/yum.conf

[root@gfs01 sysconfig]# grep ^exclude /etc/yum.conf
exclude=gluster*
(in [main] section)

parted -s -- /dev/xvdb mktable gpt
parted -s -- /dev/xvdb mkpart primary 2048s 100%
parted -s -- /dev/xvdb set 1 lvm on
partx -a /dev/xvdb
pvcreate /dev/xvdb1 
vgcreate vggfs01 /dev/xvdb1 

lvcreate -l 100%VG -n gbrick1 vggfs01
mkfs.xfs -i size=512 /dev/vggfs01/gbrick1
echo '/dev/vggfs01/gbrick1 /data/gluster/gvol0 xfs inode64,nobarrier 0 0' >> /etc/fstab
mkdir -p /data/gluster/gvol0
mount /data/gluster/gvol0
mkdir -p /data/gluster/gvol0/brick1

/bin/systemctl start glusterd.service
/bin/systemctl status glusterd.service
systemctl enable glusterd.service

>> On NODE2
gluster peer probe gfs01
gluster peer status
gluster pool list

>> On NODE1
gluster peer probe gfs02
gluster peer status
gluster pool list

gluster volume create gvol0 replica 2 transport tcp gfs01:/data/gluster/gvol0/brick1 gfs02:/data/gluster/gvol0/brick1
gluster volume start gvol0
gluster volume info gvol0

gluster volume set gvol0 performance.cache-refresh-timeout 30
gluster volume set gvol0 performance.io-thread-count 32
gluster volume set gvol0 performance.cache-size 1073741824
gluster volume info gvol0



============================================================

TO MOUNT - Fuse (HA)
=> nodes need to be connected to the same Cloud Network

Append to /etc/hosts
# GlusterFS
192.168.3.5     gfs01
192.168.3.6     gfs02

yum -y install glusterfs glusterfs-fuse

modprobe fuse

echo 'gfs01:/gvol0 /mnt/gluster/gvol0 glusterfs defaults,backupvolfile-server=gfs02,_netdev 0 0' >> /etc/fstab

mkdir -p /mnt/gluster/gvol0

mount /mnt/gluster/gvol0


==========================================================
It seems that Debian 7 cannot have GlusterFS 3.7 but only from Debian 8.
http://download.gluster.org/pub/gluster/glusterfs/3.7/3.7.0/Debian/jessie/


==========================================================

Extra source: http://matty.digital/gluster

Extra commands
# gluster volume remove-brick gvol0 gfs02:/data/gluster/gvol0/brick1 force
# gluster peer detach gfs02
# gluster peer detach gfs01
# gluster peer probe gfs01

GIT basic commands

Check branch

git branch <name new branch>

Show changes after your last commit

git diff

rollback to previous change (specific file) to the latest commit

git checkout -- testfile

Delete branch

git branch -D <branch name>

Push new branch to the origin (my ‘git space’)

git push -u origin <branch name>

Restore file from upstream

git checkout upstream/master -- <filename>

Commit changes in one single line

git commit -a -m "comment"

If you want to merge the recent changes committed on the master branch into your dev branch

git checkout dev      # gets you "on branch dev"
git fetch origin        # gets you up to date with origin
git merge origin/master

If you want to reset ALL from the version ‘on the web’

git fetch origin
git reset --hard origin/<branch>

Source: http://rogerdudler.github.io/git-guide/

Docker basic commands

Check containers

# docker ps -a

Connect to a container

# docker start <ID>
# docker attach <ID>

Exit from a container

-> type 'exit'

Remove all of Docker containers:

docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)

NSCD – Cache DNS requests

DNS queries can be an issue on Cloud infrastructure, where SaaS are generally configured using FQDN instead of IP. This means that every time your application needs MySQL or Redis or any of the Platform/Software as a service, a DNS query will be issued.

Sometimes this could hammer the local DNS and service providers might block your DNS traffic.

To minimise this, you could use nscd to cache the DNS queries and reduce the traffic to the local DNS servers.

>> Test if port 53 has been blocked
tcpdump -vvv -s 0 -l -n port 53

>> Check what is currently cached
nscd -g (and check hosts cache)

>> Configuration file
grep -v "^#" /etc/nscd.conf (leaving only 'hosts' details)

	server-user		nscd
	debug-level		0
	paranoia		no

	enable-cache		hosts		yes
	positive-time-to-live	hosts		3600
	negative-time-to-live	hosts		20
	suggested-size		hosts		211
	check-files		hosts		yes
	persistent		hosts		yes
	shared			hosts		yes
	max-db-size		hosts		33554432

Improve/Ubuntu-like Font Rendering in Debian using Infinality Font

/etc/apt/sources.list

#Infinality Fonts
deb http://ppa.launchpad.net/no1wantdthisname/ppa/ubuntu saucy main

apt-get install fontconfig-infinality

cd /etc/fonts/infinality/
bash infctl.sh setstyle

chose 3 (i.e. linux).

In /etc/profile.d/infinality-settings.sh --> search for ā€œUSE_STYLEā€ or scroll (around line 710) till you see the option to set the style => USE_STYLE=ā€UBUNTUā€


Settings -> Appearance.

    Tick the checkbox to Enable anti-aliasing
    Set Sub-pixel order to RGB
    Set Hinting to Slight


======================================

Personally installed before also: cabextract fonts-liberation ttf-mscorefonts-installer


======================================

Other fonts:

1) Install pretty fonts (you'll need non-free for mscorefonts): apt-get install ttf-dejavu ttf-liberation ttf-mscorefonts-installer xfonts-terminus
2) dpkg-reconfigure fontconfig-config, select Autohinter, Automatic and No
3) dpkg-reconfigure fontconfig
4) Restart Xorg
5) Gnome-specific (these are largely personal preferences): System -> Preferences -> Appearances -> Fonts: Enable 'Best Shapes', Details -> Dots per Inch: 110, Smoothing -> Grayscale

======================================

Source: http://linuxpanda.wordpress.com/2014/03/14/improve-ubuntu-like-font-rendering-in-debian-using-infinality-font/

Rackspace – Reinstall Nova-Agent

apt-get purge nova-client
apt-get update && apt-get upgrade

Used this script to re-install nova-agent: https://github.com/rackerlabs/openstack-guest-agents-unix/blob/master/tools/nova-agent-builder.sh

>> extract the tar and ./install.sh

sed '1i### BEGIN INIT INFO\n# Provides: Nova-Agent\n# Required-Start: $remote_fs $syslog\n# Required-Stop: $remote_fs $syslog\n# Default-Start: 2 3 4 5\n# Default-Stop: 0 1 6\n# Short-Description: Start daemon at boot time\n# Description: Enable service provided by daemon.\n### END INIT INFO\n' /usr/share/nova-agent/1.39.1/etc/generic/nova-agent > /usr/share/nova-agent/1.39.1/etc/generic/nova-agent.lsb

cp /usr/share/nova-agent/1.39.1/etc/generic/nova-agent.lsb /etc/init.d/nova-agent

chmod +x /etc/init.d/nova-agent

service xe-linux-distribution stop
service xe-linux-distribution start
service nova-agent start

# ps aux | grep nova
root      7874  0.0  0.7 143984  7464 ?        Ssl  09:02   0:00 /usr/sbin/nova-agent -q -p /var/run/nova-agent.pid -o /var/log/nova-agent.log -l debug /usr/share/nova-agent/nova-agent.py
root      7890  0.0  0.0  11980   928 pts/0    S+   09:03   0:00 grep --color=auto nova


Sources:
http://www.syntheticworks.com/rackspace-cloud/linux-rackspace-cloud/all-about-nova-agent-linux/
https://github.com/rackerlabs/openstack-guest-agents-unix/blob/master/tools/nova-agent-builder.sh
http://bootrackspacecom.readthedocs.org/en/latest/nova_agent/