Monday, September 26, 2011

XenServer Backup Script

This handy bash script I wrote, enables Xen Server Administrators to create On-Line backups (Importing the VM into.xva file) while the backed up virtual machine is up and running.

I found this extremely useful for big production environments - where lots of VM's require an appropriate & efficient back-up solution and downtime is not an option.

The script is very simple and user friendly, it's executed as root from the dom0 machine and used as follows:
In order to list all the available VM's on the system:
#./xen_onlinebackup.sh -l

In order to back up a VM:
#./xen_onlinebackup.sh -p /path/to/backupdir -s vm-name

The script supports both interactive and unattended mode (-u flag), the later designed to be built into scripts as an automation solution for large production environments.

For any help/usage, just run:
#./xen_onlinebackup.sh -h

Tested succesefully on XenServer 5.6 FP1 & XenServer 5.6 SP2.
Any comments, feed-backs or suggestions for improvements are very welcomed.


 #!/bin/bash
#
#This script used to create XenServer VM's online backup #Importing the VM into .xva file #Written by Paul Podolny - July 2011

#Variables
COUNT=0
AUTO=0 #Used for unattended mode
VMLIST=`xe vm-list is-control-domain=false |grep -i name-label|awk -F": " '{print $2}'`

#Functions
list() {
echo "====================================="
echo "Listing available VM's on $HOSTNAME..."
echo "====================================="
for i in $VMLIST;do
      echo $i;let COUNT+=1
done
echo "================================="
echo "Total $COUNT Virtual Machines"
echo "================================="
exit 0
}

usage() {
cat << EOF
This script will backup your Xen VMs on-line:
------
Usage:
------
-h Help/Usage.
-l List VM's.
-u Run in unattended mode (No questions asked).
-s Server Name (Backed Up VM).
-p Path to backup.

--------
Example:
--------
$0 -s server01 -p /nfs/backupdir/ -u
EOF
exit 0
}
check_dir() {
echo "=============================================================="
echo "XenServer Online Backup"
echo "=============================================================="
if  [ -e ${BACKUPPATH}/${VMNAME} ];then
        echo "Directory ${VMNAME} on path ${BACKUPPATH} seem to exist, will use it."

else
      echo "Creating dir. ${VMNAME} on backup path: ${BACKUPPATH}"
      mkdir ${BACKUPPATH}/${VMNAME}
fi

echo "`date +%H:%M` Backing Up ${VMNAME}, please hold on...Do NOT interrupt with CTRL+C !!!"
echo "================================================="
}


################################
#MAIN Prog
################################
while getopts "s:p:lhu" flag ; do
        case $flag in
                l ) list;;
                s ) VMNAME=$OPTARG;;
                p)  BACKUPPATH=$OPTARG;;
                h ) usage;;
                u)  AUTO=1;;
                *)  usage;;
        esac
done

#Sanity check  - Make sure backup path + VM name specificed if [ -z ${VMNAME} ] || [ -z ${BACKUPPATH} ];then echo  "Error:Both backup path AND VM name must be specified, exiting..."
echo  "Use $0 -h  for help"
exit 1
fi

#If running in interactive mode
if [ ${AUTO} != "1" ];then
      echo "Going to back-up ${VMNAME} to ${BACKUPPATH} ,is this OK? [y/n]"
      read ANSWER
      if [ ${ANSWER} != "y" ] && [ ${ANSWER} != "Y" ];then
            echo "Exiting by users request..."
            exit 1
      fi
fi
      #else proceed with main program...
      else
            check_dir
            TEMPUUID=$(xe vm-snapshot vm=$VMNAME new-name-label=snap_tmp_`date +%F`)
            xe template-param-set is-a-template=false ha-always-run=false uuid=$TEMPUUID
            xe vm-export vm=${TEMPUUID} filename=${BACKUPPATH}/${VMNAME}/${VMNAME}_backup_`date +%F`.xva
            echo "Removing Temporary Snapshot....(DO NOT PANIC!)"
            xe vm-uninstall uuid=${TEMPUUID} force=true
            echo "==============================================================="
            echo "### Back Up of ${VMNAME} Completed!###"
            echo  "`date +%H:%M`"

#END OF SCRIPT

Thursday, September 22, 2011

Adding Users in OpenLDAP

In this quick tutorial I will show how to add users to your directory.
I will be using two CentOS 5.5 x64 hosts for this presentation:
  • server - will be my test OpenLDAP server.
  • test - will be my test client host.
Before we begin I will assume OpenLDAP is already correctly installed on your system  (you can refer to this procedure, to learn more about primary OpenLDAP installation & configuration).

In this example my root dn is:"dc=example,dc=org"
And my admin user on the LDAP server is "cn=Manager,dc=example,dc=org"

OK, let's get our hands dirty:

Server side:
First, check that LDAP server is installed and running:
root@server# rpm -qa|grep -i ldap
openldap-2.3.43-12.el5_6.7
openldap-clients-2.3.43-12.el5_6.7
nss_ldap-253-25.el5
openldap-servers-2.3.43-12.el5_6.7
php-ldap-5.1.6-27.el5
nss_ldap-253-25.el5
openldap-2.3.43-12.el5_6.7
root@server# lsof -i :389
COMMAND   PID USER   FD   TYPE  DEVICE SIZE NODE NAME
slapd   20221 ldap    7u  IPv6 4349285       TCP *:ldap (LISTEN)
slapd   20221 ldap    8u  IPv4 4349286       TCP *:ldap (LISTEN)

Next, we will add a user and change it's password:
root@server# useradd -g ldap-users john
root@server# passwd john

Now, we will copy user's "john" data from /etc/passwd and use one of the migration scripts OpenLDAP provides in order to create an appropriate "ldif" file:

root@server# grep john /etc/passwd > /etc/openldap/passwd.john
root@server# /usr/share/openldap/migration/migrate_passwd.pl /etc/openldap/passwd.john /etc/openldap/passwd.john.ldif

We will add the newly created "ldif" file into our LDAP DB:

root@server# ldapadd -x -D "cn=Manager,dc=example,dc=org" -W -f  /etc/openldap/passwd.john.ldif

Enter LDAP Password:  
adding new entry "uid=john,ou=People,dc=example,dc=org"

Let's try to search for john user in the LDAP DB:

root@server# ldapsearch -x -LLL '(uid=john)'
dn: uid=john,ou=People,dc=example,dc=org
uid: john
cn: john
objectClass: account
objectClass: posixAccount
objectClass: top
objectClass: shadowAccount
userPassword:: e2NyeXB0fSEh
shadowLastChange: 15239
shadowMin: 0
shadowMax: 99999
shadowWarning: 7
loginShell: /bin/bash
uidNumber: 500
gidNumber: 500
homeDirectory: /home/john

Seems to be working, now let's switch to the client.


Client side:
Check that your client is configured with the LDAP server:
Add the server and the domain inside: /etc/ldap/ldap.conf

uri ldap://server.example.org/
base dc=example,dc=org

Edit /etc/nsswitch.conf for LDAP authentication:

passwd: files ldap
shadow: files ldap
group: files ldap

It's time to test our configuration from the client side:
First check that john isn't listed in your /etc/passwd local  file:

root@test# grep john /etc/passwd
root@test#

As we can see, no john here.
Now try to "id" john:

root@test# id john
uid=500(john) gid=500 groups=500

Just as we wanted.

Monday, September 12, 2011

Import/Export MySQL Databases

Well to be honest, this is quite trivial but useful nevertheless so I will get straight to the point:


In order to export a DB into a file:
#mysqldump -u username -p{password} database_name > dbfile.sql
   
In a scenario where multiple DB's need a backup solution
A simple script like this can be implemented:

#!/bin/bash
for i in `mysql -e "show databases;" |egrep -v '^Database$'`; do
#dump and backup to remote server
mysqldump -Q |gzip -cf >/backupdir/db_${i}-`date + %F`.sql.gz
rsync -avz -e ssh /backupdir/. server:/remote_dir/. 
done


To import an exported DB from a file:

# mysql -u username -p db_name < dbfile.sql