Новая версия скрипта для бэкапа OpenLDAP-баз

LDAP
Каждый раз создаётся полный бэкап slapcat'ом
Если предыдущего бэкапа нет (первый запуск, например) — просто делаем первый полный бэкап
Если есть предыдущий полный бэкап, сравниваем текущий полученный бэкап с предыдущим
Если разница есть, то она записывается degrade-патчем (то есть позволяющим получить предыдущую версию из самой свежей), если разницы нет — просто чистятся файлы в /tmp

Если директории для бэкапов нет, она создаётся

Все переменные настроек — в начале скрипта
#!/bin/bash
LDAP_URI='ldap://127.0.0.1'
BIND_DN='cn=config'
BIND_PW='********'
BAK_ROOT='/bak'
OL_BIN_DIR='/opt/OpenLDAP/current/Binaries/exe'
OL_SYSBIN_DIR="${OL_BIN_DIR}/sys"
pfxFullBak='fullbak'
pfxDegradePatch='diff'

declare -a lstTmpFiles=()

setDbROFlag () {
local newState=$1
 [[ $newState =~ ^(TRUE|FALSE)$ ]] || return 1
 ldapmodify -x -D "$BIND_DN" -w "$BIND_PW" <<EOF
dn: olcDatabase=$olcDatabase,cn=config
changeType: modify
replace: olcReadOnly
olcReadOnly: $newState
EOF
}  
   
doSlapDumpDb () {
 slapcat -F "$olcConfigDir" -n $dbID > "$1"
 if [[ $flDbStateSwitched == 1 ]]; then
  setDbROFlag FALSE
  flDbStateSwitched=0
 fi
 return $?
}
 
ehndlCleanAllAndExit () {
 [[ $lstTmpFiles ]] && rm -f ${lstTmpFiles[*]}
 [[ $flDbStateSwitched == 1 ]] && setDbROFlag FALSE
 exit 1
}
 
hash -p "${OL_SYSBIN_DIR}/slapcat" slapcat
for i in search modify; do hash -p "${OL_BIN_DIR}/ldap${i}" ldap${i}; done

flDbStateSwitched=0
trap ehndlCleanAllAndExit SIGHUP SIGINT SIGTERM

eval "`ldapsearch -xLLL -D "$BIND_DN" -w "$BIND_PW" -b 'cn=config' -s base olcConfigDir | \
        sed -nr 's%^olcConfigDir: (.+)$%olcConfigDir=\"\1\"%p'`"
        
while read attr; do
 if [[ $attr ]]; then
  eval "${attr/\: /=}"
 else
  flFullBakOnly=0
  dbID=${olcDatabase//[^0-9]/}
  
  bakDir="$BAK_ROOT/$olcDbDirectory"
  if ! [[ -d "$bakDir" ]]; then
   flFullBakOnly=1
   mkdir -p "$bakDir"
  fi
  cd "$bakDir"
  
  if [[ ${olcReadOnly:-FALSE} == FALSE ]]; then
   setDbROFlag TRUE
   flDbStateSwitched=1
  fi
    
  [[ $flFullBakOnly == 0 ]] && \
   latestFullBak_Ts=$(ls -t ${pfxFullBak}*.ldif | \
                     sed -nr "s%^${pfxFullBak}-([1-9][0-9]-(0[0-9]|1[0-2])-([0-2][0-9]|3[0-1])_([0-1][0-9]|2[0-3])(:[0-5][0-9]){2})\.ldif$%&/\1%p")
  if [[ $latestFullBak_Ts && $flFullBakOnly == 0 ]]; then
   latestFullBak=${latestFullBak_Ts%%/*}
    
   bp=${#lstTmpFiles}
   lstTmpFiles+=($(mktemp /tmp/XXXXXXXX))
   lstTmpFiles+=($(mktemp /tmp/XXXXXXXX))
   
   tmpNewFullBak=${lstTmpFiles[$bp]}
   tmpDegradePatch=${lstTmpFiles[$((bp+1))]}

   doSlapDumpDb "$tmpNewFullBak"
   
   if diff -uNr "$tmpNewFullBak" "$latestFullBak" >"$tmpDegradePatch" 2>/dev/null; then
    rm -f "$tmpNewFullBak" "$tmpDegradePatch"
   else
    _now=$(date +%y-%m-%d_%H:%M:%S)
    _was=${latestFullBak_Ts##*/}   
    mv "$tmpNewFullBak" "${pfxFullBak}-${_now}.ldif"
    mv "$tmpDegradePatch" "${pfxDegradePatch}-F(${_now})_T(${_was}).patch"
    rm -f "$latestFullBak"
   fi
   unset lstTmpFiles[$bp+1] lstTmpFiles[$bp]
  else
   doSlapDumpDb "${pfxFullBak}-$(date +%y-%m-%d_%H:%M:%S).ldif"
  fi  
 fi   
done < <(ldapsearch -xLLL -H $LDAP_URI -D "$BIND_DN" -w "$BIND_PW" -b 'cn=config' -s one \
 '(&(objectClass=olcDatabaseConfig)(|(objectClass=olcHdbConfig)(objectClass=olcBdbConfig)))' olcDatabase olcDbDirectory olcReadOnly)

4 комментария

avatar
у меня оцень цуцуть, как то по детски)))

#!/bin/bash
# script ver.1.0 to create dump OpenLDAP
#########################################
# setting environment variable
HOSTNAME=`/bin/hostname`
DUMP_DATE=`/bin/date "+%Y-%m-%d"`
DUMP_DATE_OLD=`/bin/date --date='-4 weeks' '+%Y-%m-%d'`
DUMP_PATH="/repo/backup/OpenLDAP/"
DUMP_NAME="$HOSTNAME"_"$DUMP_DATE".ldif
DUMP_NAME_OLD="$HOSTNAME"_"$DUMP_DATE_OLD".ldif
DUMP_FULL_PATH="$DUMP_PATH""$DUMP_NAME"
DUMP_FULL_PATH_OLD="$DUMP_PATH""$DUMP_NAME_OLD"
SLAPD="/etc/init.d/slapd"
SLAPCAT="/usr/sbin/slapcat -l"
SLAPCAT_RUN="$SLAPCAT $DUMP_FULL_PATH"
#########################################
$SLAPD stop
PID_file=/var/run/slapd/slapd.pid
if [[ -e $PID_file ]]
 then
  echo "slapd is not stopped..."
  echo "script is stopped!!!"
  exit 1
fi
#########################################
$SLAPCAT_RUN
if [[ -e $DUMP_FULL_PATH ]]
  then
  echo "OpenLDAP database dump is written to the file!"
  $SLAPD start
  PID_number=`cat /var/run/slapd/slapd.pid`
   if [ -n "$PID_number" ]
    then
     echo "slapd is running...ProcessID $PID_number"
      rm -rf $DUMP_FULL_PATH_OLD
     exit 0
    else
     echo "slapd is not running!!!"
     exit 1
   fi
fi
#########################################
echo "OpenLDAP database dump is NOT written!!!"
$SLAPD start
PID_number=`cat /var/run/slapd/slapd.pid`
if [ -n "$PID_number" ]
 then
  echo "slapd is running...ProcessID $PID_number"
  exit 0
fi
echo "slapd is not running!!!"
exit 1
avatar
ну если хватает, то итак хорошо. Мне, например, просто нельзя останавливать LDAP-сервер: его почтовик и DNS активно атакуют запросами. Ну и я учёл то, что баз может быть несколько :)
avatar
Спасибо.

Для FreeBSD сменить «sed -nr» на «sed -nEe»
В остальном работает.
avatar
Спасибо.
Такие скрипты могу читать часами не отрываясь, как кульминация в любой книге, важен каждый момент )
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.