Difference between revisions of "Bacula and Bareos"

From Hack Sphere Labs Wiki
Jump to: navigation, search
(Configure On CentOS 6.5)
(Configure On CentOS 6.5)
Line 32: Line 32:
 
  nano /etc/bareos/vchanger
 
  nano /etc/bareos/vchanger
  
</pre>
+
<pre>
  
  

Revision as of 12:00, 3 March 2014

CentOS 6.5 Install

yum install mysql-server mysql-devel
service mysqld start
chkconfig mysqld on
mysqladmin -u root password Y0uR3l173P455w0rd


yum  install bareos-database-mysql
yum  install bareos


/usr/lib/bareos/scripts/create_bareos_database -u root -p
/usr/lib/bareos/scripts/make_bareos_tables -u root -p
/usr/lib/bareos/scripts/grant_bareos_privileges -u root -p


service bareos-dir start
service bareos-sd start
service bareos-fd start

Links

Archlinux GUI Admin

yaourt bareos-bat

Configure On CentOS 6.5

nano /etc/bareos/vchanger


#!/bin/sh
#
#  Bacula interface to virtual autochanger using removable disk drives
#
#  Based (somewhat) on the "disk-changer" script from bacula 1.39.26
#
#  Vchanger is a Bacula autochanger script that emulates a conventional
#  magazine-based tape library device using removable disk drives.
#  Partitions on the removable drives are used as virtual magazines,
#  where each "magazine" contains the same number of virtual slots. Each
#  "slot" holds one virtual tape, where a "tape" is a regular file that
#  Bacula treats as a "Device Type = File" volume.
#
#  This script will be invoked by Bacula using the Bacula Autochanger
#  Interface and will be passed the following arguments:
#
#  vchanger "changer-device" "command" "slot" "archive-device" "drive-index"
#                 $1            $2       $3          #4             #5
#
#  See the Bacula documentation and the Bacula Removable Disk Howto for
#  further details.
#
#  Copyright (C) 2006 Josh Fisher
#
#  Permission to use, copy, modify, distribute, and sell this software
#  and its documentation for any purpose is hereby granted without fee,
#  provided that the above copyright notice appear in all copies.  This
#  software is provided "as is" without express or implied warranty.
#
#  This software is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# $Id: vchanger,v 0.7.4 2006/12/01 09:29:04 jfisher Exp $

#
# log whats done
#
# to turn on logging, uncomment the following line
#touch $wd/vchanger.log
#

#
# Write to a log file
#    To log debugging info, create file /var/bacula/vchanger.log
#    with write permission for bacula-sd user. To stop logging,
#    delete file /var/bacula/vchanger.log
#
dbgfile="/var/bacula/vchanger.log"
function debug()
{
    if test -e $dbgfile; then
	echo "`date +\"%Y%m%d-%H:%M:%S\"` $*" >> $dbgfile
    fi
}

#
# Return length of string $1
#
if [ `uname` = "FreeBSD" ]
then
        function strlen ()
        {
                expr -- "$1" : ".*"
        }
else
        function strlen ()
        {
                expr length $1
        }
fi


#
# Prepend zeros to $1 and return a string that is $2 characters long
#
function mklen ()
{
   o1=$1
   while [ `eval strlen ${o1}` -lt ${2} ]; do
      o1="0${o1}"
   done
   echo $o1
}

#
# Get uid of $1 (or current user if $1 empty)
#
function get_uid() {
   id $1 2>/dev/null | cut -d ' ' -f 1 | sed "s/uid=//" | cut -d '(' -f 1
}


#
# Initialize autochanger's state directory if not already initialized
#
function init_statedir() {
   debug "Initializing $statedir"
   # Create state directory if needed
   if [ ! -d "${statedir}" ]; then
      if [ "$su_uid" != "" ]; then
         su -c "mkdir ${statedir} &>/dev/null" $su_uid
      else
         mkdir ${statedir} &>/dev/null
      fi
      if [ $? -ne 0 ]; then
         echo "Could not create ${statedir}"
         exit 1
      fi
      chmod 770 ${statedir} &>/dev/null
      if [ $? -ne 0 ]; then
         echo "Could not chmod ${statedir}"
         exit 1
      fi
   fi
   # Create nextmag file to hold max magazine index used
   if [ ! -f "${statedir}/nextmag" ]; then
      if [ "$su_uid" != "" ]; then
         su -c "echo 0 >${statedir}/nextmag" $su_uid
      else
	     echo 0 >${statedir}/nextmag
      fi
      if [ $? -ne 0 ]; then
         echo "Could not create ${statedir}/nextmag"
         exit 1
      fi
      chmod 660 ${statedir}/nextmag
      if [ $? -ne 0 ]; then
         echo "Could not chmod ${statedir}/nextmag"
         exit 1
      fi
   fi
   # Check nextmag value
   nextmag=`cat "${statedir}/nextmag"`
   if [ $? -ne 0 -o "${nextmag}" == "" -o $nextmag -lt 0 -o $nextmag -gt 99 ]; then
      echo "${statedir}/nextmag has invalid value"
      return 1
   fi
   # Create 'loaded' files for each virtual drive that hold the slot
   # number currently loaded in that 'drive'
   i=0
   while [ $i -le $maxdrive ]; do
      if [ ! -f "${statedir}/loaded${i}" ]; then
         if [ "$su_uid" != "" ]; then
            su -c "echo 0 >${statedir}/loaded${i}" $su_uid
         else
            echo 0 >${statedir}/loaded${i}
         fi
         if [ $? -ne 0 ]; then
            echo "Could not create ${statedir}/loaded${i}"
            exit 1
         fi
         if [ "$su_uid" != "" ]; then
            su -c "chmod 660 ${statedir}/loaded${i}" $su_uid
         else
            chmod 660 ${statedir}/loaded${i}
         fi
         if [ $? -ne 0 ]; then
            echo "Could not chmod ${statedir}/loaded${i}"
            exit 1
         fi
      fi
      i=`expr ${i} + 1`
   done
}


#
# Get magazine index of currently loaded magazine
#
function get_magazine() {
   debug "Get magazine index"
   # Check for mountpoint dir
   if [ ! -d ${mountpoint} ]; then
      echo "No magazine loaded at ${mountpoint}"
      exit 1
   fi
   # Check magazine for existing index
   if [ ! -f "${mountpoint}/index" ]; then
      echo "00"
      return 1
   fi
   mi=`cat "${mountpoint}/index"`
   if [ $? -ne 0 ]; then
      echo "Failed to read ${mountpoint}/index"
      exit 1
   fi
   # must be 1-99
   if [ $mi -lt 1 -o $mi -gt 99 ]; then
      echo "Magazine has invalid index ${mi}"
      exit 1
   fi
   # make magazine index 2 digits
   eval mklen ${mi} 2
   return 0
}

#
# Initialize magazine if not already initialized
#
function init_magazine() {
   debug "Initializing magazine"
   # Get max magazine index that has been used
   nextmag=`cat "${statedir}/nextmag"`
   if [ $? -ne 0 -o "${nextmag}" == "" ]; then
      echo "Failed to read ${statedir}/nextmag"
      exit 1
   fi
   # Check magazine for existing index
   if [ -f "${mountpoint}/index" ]; then
      # retrieve existing magazine index
      mi=`cat "${mountpoint}/index"`
      if [ $? -ne 0 ]; then
         echo "Failed to read ${mountpoint}/index"
         exit 1
      fi
      # must be 1-99
      if [ $mi -lt 1 -o $mi -gt 99 ]; then
         echo "Magazine has invalid index ${mi}"
         exit 1
      fi
   else
      # new magazine, so assign it the next avail index
      mi=`expr ${nextmag} + 1`
      if [ $mi -lt 0 -o $mi -gt 99 ]; then
         echo "Max magazines exceeded"
         exit 1
      fi
      if [ "$su_uid" != "" ]; then
         su -c "echo ${mi} >${mountpoint}/index" $su_uid
      else
         echo ${mi} >${mountpoint}/index
      fi
      if [ $? -ne 0 ]; then
         echo "Failed to write ${mountpoint}/index"
         exit 1
      fi
      chmod 640 ${mountpoint}/index 2>/dev/null
   fi
   # make sure max index used is up to date
   if [ $mi -gt $nextmag ]; then
      echo $mi 2>/dev/null >"${statedir}/nextmag"
      if [ $? -ne 0 ]; then
         echo "Failed to update ${statedir}/nextmag"
         exit 1
      fi
   fi
   # make magazine index 2 digits
   magindex=`eval mklen ${mi} 2`
   # setup slot files (ie. virtual tapes)
   i=1
   while [ $i -le $magslots ]; do
      s=`eval mklen ${i} 3`
      f="${mountpoint}/m${magindex}s${s}"
      if [ ! -f "${f}" ]; then
         if [ "$su_uid" != "" ]; then
            su -c "touch ${f} &>/dev/null" $su_uid
         else
            touch ${f} &>/dev/null
         fi
         if [ $? -ne 0 ]; then
            echo "Failed to create ${f}"
            exit 1
         fi
      fi
      i=`expr ${i} + 1`
   done
   return 0
}


#
# Get sd status with bconsole
#
function bconsole_sd_status() {
   debug "Doing 'status storage' with bconsole"
   $bconsole <<EOD_SDSTAT
status storage=$baculasd
quit
EOD_SDSTAT
}


#
# Delete volume with bconsole  param1 = slot
#
function bconsole_delete_volume() {
   debug "Doing 'delete volume' with bconsole"
   s=`eval mklen $1 3`
   $bconsole <<EOD_DELVOL
delete volume=m${magindex}s${s}
yes
quit
EOD_DELVOL
}


#
# Label volumes from barcodes with bconsole
#
function bconsole_label_barcodes() {
   debug "Doing 'label barcodes' with bconsole"
   $bconsole <<EOD_SDSTAT
label storage=$baculasd pool=$purgepool drive=0 barcodes
yes
quit
EOD_SDSTAT
}

#
# Checks if any of magazine's volumes are in use
#
function volumes_in_use() {
   debug "Checking for in use volumes"
   inuse=""
   bconsole_sd_status | while read f; do
      #echo $f
      a=`echo ${f} | grep ^${magindex}`
      if [ "$a" != "" -a "$inuse" == "" ]; then
         inuse=`echo $f | cut -d ' ' -f 1`
      fi
   done
   if [ "$inuse" != "" ]; then
      echo $inuse
   fi
}


#
# Unload all drives
#
function unload_drives() {
   debug "Unloading all drives"
   vuse=`eval volumes_in_use`
   if [ "${vuse}" != "" ]; then
      return 1
   fi
   i=0
   while [ $i -le $maxdrive ]; do
      unlink "${statedir}/drive${i}" 2>/dev/null >/dev/null
      echo "0" >"${statedir}/loaded${i}"
      i=`expr ${i} + 1`
   done
   return 0
}


#
# check parameter count on commandline
#
function check_parm_count() {
    pCount=$1
    pCountNeed=$2
    if test $pCount -lt $pCountNeed; then
	echo "usage: vchanger ctl-device command [slot archive-device drive-index]"
	echo "	Insufficient number of arguments arguments given."
	if test $pCount -lt 2; then
	    echo "  Mimimum usage is first two arguments ..."
	else
	    echo "  Command expected $pCountNeed arguments"
	fi
	exit 1
    fi
}

# Setup arguments
check_parm_count $# 2
ctl=$1
cmd=$2
slot=$3
device=$4
drive=$5

# Setup default config values
baculasd=
baculasd_user=bacula
bconsole="/etc/bacula/bconsole"
magslots=10
maxdrive=0
mountpoint=
purgepool="Scratch"
statedir=

# Pull in conf file
if [ -f $ctl ]; then
   . $ctl
else
   echo "Config file ${ctl} not found"
   exit 1
fi

# When invoked by root, create files/dirs as bacula-sd user
su_uid=
myuid=`eval get_uid`
if [ "$myuid" == "0" -a "$baculasd_user" != "" ]; then
   buid=`eval get_uid $baculasd_user`
   if [ "$buid" == "" ]; then
      echo "bacula-sd user $baculasd_user not found"
      exit 1
   fi
   if [ "$buid" != "0" ]; then
      su_uid=baculasd_user
   fi
fi

# check for required config values
if [ "${mountpoint}" == "" ]; then
   echo "Required variable 'mountpoint' not defined in ${ctl}"
   exit 1
fi
if [ "${baculasd}" == "" ]; then
   echo "Required variable 'baculasd' not defined in ${ctl}"
   exit 1
fi
if [ "${statedir}" == "" ]; then
   echo "Required variable 'statedir' not defined in ${ctl}"
   exit 1
fi
if [ "${magslots}" == "" -o $magslots -lt 1 -o $magslots -gt 999 ]; then
   echo "Ivalid value for 'magslots' in ${ctl}"
   exit 1
fi
if [ "${maxdrive}" == "" -o $maxdrive -lt 0 -o $maxdrive -ge $magslots ]; then
   echo "Invalid value for 'maxdrive' in ${ctl}"
   exit 1
fi
if [ "${bconsole}" == "" -o ! -f "${bconsole}" ]; then
   echo "Ivalid value for 'bconsole' in ${ctl}"
   exit 1
fi
if [ "${purgepool}" == "" ]; then
   echo "Invalid value for 'purgepool' in ${ctl}"
   exit 1
fi

# attempt to set defaults for params not specified on command line
if [ "${drive}" == "" ]; then
   drive=0
fi
if [ "${device}" == "" ]; then
   device="${statedir}/drive${drive}"
fi

# make sure archive device makes sense
if [ "${device}" != "${statedir}/drive${drive}" ]; then
   echo "Param 4 (archive device) must be ${statedir}/driveN,"
   echo "   where N is the drive number passed as param 5"
   exit 1
fi

# Initialize state directory for this autochanger
init_statedir

debug "Parms: $ctl $cmd $slot $device $drive"

#
#  Process command
#
case $cmd in
   list)
      check_parm_count $# 2
      debug "Doing list command"
      init_magazine
      if [ $? -ne 0 ]; then
         echo "Magazine Not Loaded"
         exit 1
      fi
      i=1
      while [ $i -le $magslots ]; do
         s=`eval mklen ${i} 3`
         echo "${i}:m${magindex}s${s}"
         i=`expr ${i} + 1`
      done
      ;;
   slots)
      check_parm_count $# 2
      debug "Doing slots command"
      echo $magslots
      ;;
   load)
      check_parm_count $# 5
      debug "Doing load slot $slot into drive $drive"
      if [ $drive -gt $maxdrive ]; then
         echo "Drive ($drive) out of range (0-${maxdrive})"
         exit 1
      fi
      if [ $slot -gt $magslots ]; then
         echo "Slot ($slot) out of range (1-$magslots)"
         exit 1
      fi
      ld=`cat "${statedir}/loaded${drive}"`
      if [ $? -ne 0 ]; then
         echo "Failed to read ${statedir}/loaded${drive}"
         exit 1
      fi
      if [ $ld -eq 0 ]; then
         unlink "${device}" &>/dev/null
         # make sure slot is not loaded in another drive
         i=0
         while [ $i -le $maxdrive ]; do
            if [ $i -ne $drive ]; then
               ldi=`cat "${statedir}/loaded${i}"`
               if [ $ldi -eq $slot ]; then
                  echo "Storage Element ${slot} Empty (loaded in drive ${i})"
                  exit 1
               fi
            fi
            i=`expr ${i} + 1`
         done
         init_magazine
         if [ $? -ne 0 ]; then
            echo "Magazine Not Loaded"
            exit 1
         fi
         s=`eval mklen ${slot} 3`
         if [ "$su_uid" != "" ]; then
            su -c "ln -s '${mountpoint}/m${magindex}s${s}' '${device}'" $su_uid
         else
            ln -s "${mountpoint}/m${magindex}s${s}" "${device}"
         fi
         echo $slot >"${statedir}/loaded${drive}"
      else
         echo "Drive ${drive} Full (Storage element ${ld} loaded)"
         exit 1
      fi
      ;;
   unload)
      check_parm_count $# 5
      debug "Doing unload drive $drive into slot $slot"
      if [ $drive -gt $maxdrive ]; then
         echo "Drive ($drive) out of range (0-${maxdrive})"
         exit 1
      fi
      if [ $slot -gt $magslots ]; then
         echo "Slot ($slot) out of range (1-$magslots)"
         exit 1
      fi
      ld=`cat "${statedir}/loaded${drive}"`
      if [ $? -ne 0 ]; then
         echo "Failed to read ${statedir}/loaded${drive}"
         exit 1
      fi
      if [ $slot -eq $ld ]; then
         echo "0" >"${statedir}/loaded${drive}"
         if [ $? -ne 0 ]; then
            echo "Failed to write ${statedir}/loaded${drive}"
            exit 1
         fi
         unlink "${device}" 2>/dev/null >/dev/null
         exit 0
      fi
      if [ $ld -eq 0 ]; then
         echo "Drive ${drive} Is Empty"
         exit 1
      else
         echo "Storage Element ${slot} is Already Full"
         exit 1
      fi
      ;;
   loaded)
      check_parm_count $# 5
      debug "Doing loaded command for drive $drive"
      if [ $drive -gt $maxdrive ]; then
         echo "Drive ($drive) out of range (0-${maxdrive})"
         exit 1
      fi
      if [ $slot -gt $magslots ]; then
         echo "Slot ($slot) out of range (1-$magslots)"
         exit 1
      fi
      cat "${statedir}/loaded${drive}"
      ;;
   purge)
      check_parm_count $# 2
      debug "Doing purge command"
      magindex=`eval get_magazine`
      if [ "$magazine" == "00" ]; then
         echo No magazine loaded
      fi
      cm=""
      while [ "$cm" != "y" -a "$cm" != "n" ]; do
         echo -n "Purge all volumes on magazine $magindex (y/n)? "
         read cm
         if [ "$cm" == "Y" ]; then
            cm="y"
         fi
         if [ "$cm" == "N" ]; then
            cm="n"
         fi
      done
      if [ "$cm" == "n" ]; then
         exit 0
      fi
      echo "Unloading $baculasd drives"
      unload_drives
      if [ $? -ne 0 ]; then
         echo Volume `eval volumes_in_use` in use...aborting
         exit 1
      fi
      echo "Deleting magazine $magindex volumes"
      i=1
      while [ $i -le $magslots ]; do
         bconsole_delete_volume $i &>/tmp/vclog
         rm -f "${mountpoint}/m${magindex}s${s}"
         echo "deleted volume m${magindex}s${s}"
         i=`expr ${i} + 1`
      done
      echo "Doing 'label barcodes' to re-create magazine's volumes"
      bconsole_label_barcodes | while read f; do
         echo $f
      done
      ;;
   *)
      echo "Command not recognized"
      exit 1
      ;;
esac

exit 0
# eof