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 29: Line 29:
  
 
=Configure On CentOS 6.5=
 
=Configure On CentOS 6.5=
 +
Since I use disks I start with installing vchanger
 +
*http://wiki.bacula.org/doku.php?id=removable_disk
 +
The link above has a script but it looks like the one on sourceforge (which is referenced in the link) is newer and compiles.  Even then, I decided to pull the rpm from pbone
 +
wget ftp5.gwdg.de/pub/opensuse/repositories/home:/pstorz/CentOS_CentOS-6/x86_64/vchanger-0.8.6-10.3.x86_64.rpm
 +
yum install vchanger-0.8.6-10.3.x86_64.rpm
  
nano /etc/bareos/vchanger
+
==Links==
 
+
*http://rpm.pbone.net/index.php3/stat/4/idpl/23671919/dir/centos_6/com/vchanger-0.8.6-10.3.i686.rpm.html
<pre>
+
*http://wiki.bacula.org/doku.php?id=removable_disk#vchanger
 
+
*http://superuser.com/questions/573816/how-do-i-configure-yum-to-use-additional-repositories
 
 
#!/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
 
</pre>
 

Revision as of 11:26, 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

Since I use disks I start with installing vchanger

The link above has a script but it looks like the one on sourceforge (which is referenced in the link) is newer and compiles. Even then, I decided to pull the rpm from pbone

wget ftp5.gwdg.de/pub/opensuse/repositories/home:/pstorz/CentOS_CentOS-6/x86_64/vchanger-0.8.6-10.3.x86_64.rpm
yum install vchanger-0.8.6-10.3.x86_64.rpm

Links