martes, 29 de agosto de 2017

Nuevo debian nuevos cambios

Recuerdo que Debian era más sencillo y por eso lo he preferido siempre, pero los cambios que trae debian 9 no me estan gustando. Sin embargo decidí no tirar toda una distribución solo por un poco de inconformidad. El problema inicia con el nombramiento de las interfaces, en sistemas nuevos veo que las interfaces toman nombres como "ens18", en lugar de "eth0" que es lo trandicional. "Ok", me dije, un pequeño cambio que puede luego ser renombrado, solo es un label, pero luego cuando quise establecer el ip de la forma tradicional editando "/etc/network/interfaces", y haciendo un ifdown y un ifup tradicional, me lleve la gran sorpresa que no ocurria nada, adicionando que "net-tools" no venía incluido por defecto, lo cual me sorprendió. Leyendo un poco al final resolví el acertijo, en debian9 ya no se puede hacer ifdown y un ifup de forma tradicional, al menos no con la versión que he instalado que es la "9.1" entiendo que es la última. La forma bajo la cual realice lo deseado sin tener que apagar el equipo fueron los siguientes pasos: # ifdown ens18 # ip address del 172.20.5.5 dev ens18 # vim /etc/network/interfaces # /etc/init.d/networking restart Con esto logré realizar el cambio de ip sin tener que reiniciar.

martes, 18 de julio de 2017

Escribiendo Scripts para crear un respaldo usando mariadb como base de datos

Hacer un respaldo con mysqldump es algo que mola mucho y va de pasada, pero a veces tenemos un servidor con tantos usuarios y tantas bd que estar creando un script con un comando mysql que por parámetro con la opción '-e' le pasemos las consultas para hacer una query para obtener todas las bd, a veces puede resultar en catastrofes al darnos cuenta que mysqldump no respaldó toda la bd desde hace meses y que no lo ha venido haciendo correctamente, por lo tanto necesitamos un metodo más fiable que haga en verdad su trabajo y es acá donde entra xtrabackup.

Como me gusta trabajar en scripts les comparto un script diseñado por mi para que alivie sus necesidades. Si encuentran algun bug me avisan y recuerden que deben ajustarlo a sus necesidades, aún voy a liberar una nueva versión donde pregunte si el respaldo es nfs o no, si lo es, que se pase por parámetro el ip remoto, por ahora es estático y se debe comentar la parte donde se monta el nfs remoto en caso de no tener uno:

#!/bin/bash

Scripts_path="/Scripts"

femail="webmaster@dominio.ejemplo.test"
temail="soporte@dominio.ejemplo.test" 

#Aqui va el ip del servidor nfs donde se ha de montar el respaldo
ipnfs="192.168.1.20"

dest="/backup"

host="localhost"
port=3306
user="backup"
password="U2FsdGVkX18WWIZ2IUg2hs+E8UWC82jp9jml40ruOJM="

hostname=$(hostname)
tool_mode="xtrabackup"

error_log=/var/log/$(echo $tool_mode)-backupm.log
lock_file=/tmp/$(echo $tool_mode)-backupm.lck

main_path="$dest/$hostname/$tool_mode"

last_full_backup="$main_path/last_full_backup.txt"
incremental_reg_backup="$main_path/incremental_reg_backup.txt"

history_full_backup="$main_path/history_full_backup.txt"
history_incremental_reg_backup="$main_path/history_incremental_reg_backup.txt"

function montar(){
  montado=$(cat /etc/mtab | grep backup | wc -l)
  if let "montado==0";then
    echo "Mounting $ipnfs:/nfs/dbserver on $dest" >> $error_log 2>&1
    mount -t nfs $ipnfs:/nfs/dbserver $dest
  fi
}
function desmontar(){
  montado=$(cat /etc/mtab | grep backup | wc -l)
  if let "montado==1";then
    echo "Unmounting $ipnfs:/nfs/dbserver on $dest" >> $error_log 2>&1
    umount $dest
  fi
}

function chk_files(){
  if [[ ! -d $main_path ]];then
    mkdir -pv $main_path >> $error_log 2>&1
  fi
  if [[ ! -f $last_full_backup ]];then
    echo "Creating $last_full_backup" >> $error_log 2>&1
    > $last_full_backup
  fi
  if [[ ! -f $incremental_reg_backup ]];then
    echo "Creating $incremental_reg_backup" >> $error_log 2>&1
    > $incremental_reg_backup
  fi
}

function do_backup(){

  host=$3
  port=$4
  user=$5
  password=$(echo $6 | openssl enc -aes-128-cbc -a -d -salt -pass pass:wtf)
  
  if [[ ! -f "$lock_file" ]];then
    > $lock_file
  fi

  if [[ "$( cat $lock_file )" != "$(date +%Y%m%d)" ]];then

    ##########################################################
    # Tomamos la fecha y ordenador al que el backup pertenece.

    Yr=$(date +"%Y")
    Mh=$(date +"%m")
    Dy=$(date +"%d")
    day=$(echo "$Yr$Mh$Dy")
    let $folder "folder=(Mh-1)%3"
    echo $day > $lock_file
    echo " day $day --- folder $folder --- month $Mh" >> $error_log 2>&1
    echo "---------------- $(date +"%Y/%m/%d - %H:%M:%S") ----------------" >> $error_log 2>&1

    backup_path="$main_path/monthly/$folder"
    if [[ ! -d $backup_path ]];then
      mkdir -pv $backup_path >> $error_log 2>&1
    fi

    #If force yes then delete
    if [[ "$2" == "1" ]]; then
      if [[ -d $backup_path ]]; then
        rm -rfv $backup_path >> $error_log 2>&1
      fi
    else
      if [[ -d $backup_path ]]; then
        error="La carpeta existe y no se hace nada use la opcion -(f) para forzar el respaldo!\n"
        print "%s" "$error" >> $error_log 2>&1
        print "%s" "$error"
        exit 1
      fi
    fi

    initialt=$(date +"%H:%H:%S")
    if [[ ! -d $dest/files ]];then
      mkdir -pv $dest/files >> $error_log 2>&1
    fi

    echo "---------------- [$day / $initialt] - [Backup of files and Scripts] ----------------" >> $error_log 2>&1

    tar -czpf $dest/files/etc.tar.gz /etc/ >> $error_log 2>&1
    tar -czpf $dest/files/Scripts.tar.gz $Scripts_path >> $error_log 2>&1

    printf "Last Script runned on %d and stored in folder %s\n" "$day" "$backup_path" >> $main_path/date.txt

    echo "---------------- [$day / $initialt] - [Initial Backup] ----------------" >> $error_log 2>&1
    xtrabackup -u $user -p $password --backup --datadir=/var/lib/mysql/ --target-dir=$backup_path >> $error_log 2>&1
    finalt=$(date +"%H:%H:%S")
    echo "---------------- [$day / $finalt] - [Final Backup] ----------------" >> $error_log 2>&1

    cat $last_full_backup >> $history_full_backup
    echo "$day [$initialt - $finalt] | $backup_path" > $last_full_backup

    echo "Cleaning old week backup" >> $error_log 2>&1
    while read weekline;do
      weekfolder=$(echo $weekline | awk '{print $6}' )
      if [ -d $weekfolder ];then
        rm -rfv $weekfolder >> $error_log 2>&1
      fi
    done < $history_incremental_reg_backup

    #Updateing incremental registry
    cat $incremental_reg_backup >> $history_incremental_reg_backup
    > $incremental_reg_backup

    rm $lock_file
  fi
}

> $error_log

option=""
force=1
nfs_option=1

flag1=0
flag2=0

print_usage() {
  backup_path="$main_path/monthly/[0-2]"

  echo "Modo de empleo: $0.sh [-F|--force] [N|--noforce] [-T|--timestamp] [-O|--notimestamp] [-U|--user=\$user] [-P|--port=\$port] [-H|--host=\$host] [-p|--password=\$password] [--no_nfs] [-h|--help]
  Realiza un respaldo completo de la base de datos usando el PATH $backup_path

  Las opciones validas son:
  -F|--force   Forzar la carpeta destino si existe reescribe
  -H|--host=\$host  Nombre del servidor a conectarse para el respaldo (default=dbserver) 
  -N|--noforce   Si la carpeta destino existe no reescribe
  -O|--notimestamp  Escribe directamente en $backup_path sin estampado de tiempo
  -P|--port=\$port  Puerto a conectarse para el respaldo (default=3306)
  -T|--timestamp  Agrega al $backup_path un directorio \$Y-\$m-\$d-\$H-\$M-\$s
  -U|--user=\$user  Usuario con el que se conectara al servidor para hacer el respaldo (default=backup)
  -h|--help   Imprime esta ayuda
  --no_nfs   No intenta montar directorio de respaldo
  -p|--password=\$password Password para la autenticacion.

  Las opciones por defectos son --force y --notimestamp

  OPTIONS: -[F|H|N|O|P|T|U|h|p] 
  " >&2
}
while [[ "$1" != "" ]]; do

  case $1 in
    -F|--force)
      if let "flag1==0";then
        let $force "force=1"
        let $flag1 "flag=1"
      fi
      ;;
    -N|--noforce)
      if let "flag1==0";then
        let $force "force=0"
        let $flag1 "flag=1"
      fi
      ;;
    --no_nfs)
      nfs_option=0
      ;;
    -T|--timestamp)
      if let "flag2==0";then
        option=""
        let $flag2 "flag2=1"
      fi
      ;;
    -O|--notimestamp)
      if let "flag2==0";then
        option="--no-timestamp "
        let $flag2 "flag2=1"
      fi
      ;;
    -U)
      user=$2
      shift
      ;;
    -P)
      port=$2
      shift
      ;;
    -H)
      host=$2
      shift
      ;;
    -p)
      password=$(echo $2 | openssl enc -aes-128-cbc -a -salt -pass pass:wtf)
      shift
      ;;
    --user=*)
      user=$(echo $1 | awk -F= '{print $2}')
      ;;
    --port=*)
      port=$(echo $1 | awk -F= '{print $2}')
      ;;
    --host=*)
      host=$(echo $1 | awk -F= '{print $2}')
      ;;
    --password=*)
      password=$(echo $1 | awk -F= '{print $2}' | openssl enc -aes-128-cbc -a -salt -pass pass:wtf)
      ;;
    -h|\?|--help)
      print_usage
      exit 0
      ;;
    *)
      printf "Comando $1 no reconocido, favor consulte ($0 -h) para ver las opciones aceptadas.\n"
      #print_usage
      exit 1
      ;;
  esac
  shift
done

if [[ "$flag2" == "0" && "$option" == "" ]];then
  option="--no-timestamp"
fi

if let "nfs_option==1";then
  montar
fi
chk_files
do_backup $option $force $host $port $user $password 
#if let "nfs_option==1";then
#  desmontar
#fi