Script shell com expect para atualização em massa para o horário de verão

500px-Timezones2008_UTC-4
Para quem trabalha com vários servidores Linux / FreeBSD atualizar todos os servidores para o horário e verão é uma tarefa cansativa e chata.
Vou disponibilizar aqui um script para ser utilizado nessa tarefa, ou seja, um script que atualizará todos os servidores listados em um arquivo e os deixará prontos para a virada do horário.
O funcionamento do script é bem simples, é composto por 3 arquivos
  • daylight.sh
  • daylight.exp
  • servidores.txt
Vou explicar rapidamente o que é cada um desses arquivos e o que fazem.
Pré-requisitos
  • expect
  • openssh

Posts relacionados

daylight.sh

É o script principal, responsável por ler os dados dos servidores do arquivoservidores.txt e repassar para o script expect que atuará nos servidores.

Arquivo daylight.sh

#!/bin/bash

# Script para atualizacao em massa, via ssh, das regras de horario de verão
# nos servidores listados no arquivo
#
# - servidores.txt
#
# Autor: Daniel K Lima
# Data: 17/10/2009
########################

# VARIAVEIS para funcionamento do script
SERVIDORES="./servidores.txt"
DAYLIGHT="./daylight.exp"

# Testa se o arquivo servidores.txt existe
if [ ! -e ${SERVIDORES} ]
 then
 echo "Arquivo 'servidores.txt' não encontrado."
 exit 1
fi

# Ler o arquivo ${SERVIDORES} e processar cada linha que contém informações
# acerca da conexão
cat ${SERVIDORES} | while read LINHA
do
 # Joga os campos em variáveis
 HOST=$(echo ${LINHA} | cut -d',' -f1)
 USERNORMAL=$(echo ${LINHA} | cut -d',' -f2)
 USERPASSWD=$(echo ${LINHA} | cut -d',' -f3)
 ROOTPASSWD=$(echo ${LINHA} | cut -d',' -f4)

 # Teste sobre repasse das variáveis
 #echo ${HOST}
 #echo ${USERNORMAL}
 #echo ${USERPASSWD}
 #echo ${ROOTPASSWD}

 # Chama o arquivo expect com os parâmetros coletados
 # Testa se o expect existe
 if [ ! -e ${DAYLIGHT} ]
  then
  echo "Arquivo com script expect ${DAYLIGHT} não encontrado"
  exit 1
 else
  # Garantir que o arquivo tenha permissão de execução
  chmod 755 ${DAYLIGHT}

  # imprimir na tela o comando que esta sendo executado
  #echo "${DAYLIGHT} ${HOST} ${USERNORMAL} ${USERPASSWD} ${ROOTPASSWD}"

  # executar o script expect com os parametros
  ${DAYLIGHT} ${HOST} ${USERNORMAL} ${USERPASSWD} ${ROOTPASSWD}
 fi

done

Nota
Recomendo fazer o download do script daylight.sh ao invés de copiar o código, ao copiar e colar alguma coisa pode ser “truncada” e erros serão inevitáveis.

daylight.exp

Contém o script expect que automatizará a conexão com os servidores baseado nos parâmetros que o script daylight.sh passar e criará os arquivos da nova timezone para o horário de verão.

Arquivo daylight.exp

#!/usr/bin/expect -f
#
set force_conservative 0;
if {$force_conservative} {
 set send_slow {1 .1}
 proc send {ignore arg} {
  sleep .1
  exp_send -s -- $arg
 }
}

# argv 0 = host a ser conectado
# argv 1 = usuario para conexao SSH
# argv 2 = senha do usuario
# argv 3 = senha do root

set timeout -1
spawn $env(SHELL)
match_max 100000
send -- "ssh -l [lindex $argv 1] [lindex $argv 0]\r"
expect "word:"
send -- "[lindex $argv 2]\r"
expect "\$ "
send -- "su - root\r"
expect "word:"
send -- "[lindex $argv 3]\r"
expect "# "
send -- "cd /usr/share/zoneinfo/America\r"
expect "# "
send -- "cat > Sao_Paulo.zic << EOF\r"
expect "> "
send -- "Rule Brazil 2009 only - Oct 18 00:00 1 S\rRule Brazil 2010 only - Feb 21 00:00 0 -\r\rZone Brazil/East -3:00 Brazil BR%sT"
send -- "\r"
expect "> "
send -- "EOF\r"
expect "# "
send -- "zic Sao_Paulo.zic\r"
expect "# "
send -- "alias cp='cp'\r"
expect "# "
send -- "cp Sao_Paulo /etc/localtime\r"
expect "# "
send -- "date\r"
expect "# "
send -- "exit\r"
expect "\$ "
send -- "exit\r"
expect "$ "
send -- " "
expect eof

Nota
Recomendo fazer o download do script daylight.exp ao invés de copiar o código, ao copiar e colar alguma coisa pode ser “truncada” e erros serão inevitáveis, como por exemplo o envio das teclas Ctrl+D que não aparece no código listado acima.

servidores.txt

Contém a lista de servidores com usuário normal, senha do usuário normal e senha do root.
O formato desse arquivo é bem simples:
host,usuario_normal,senha_usuario_normal,senha_root
Note que os parâmetros são separados por vírgula.
Um exemplo desse arquivo ficaria assim:
192.168.32.20,master,xP57KLXu,89MX1sPSys3P
192.168.8.14,master,xP57KLXu,89MX1sPSys3P
192.168.32.42,master,xP57KLXu,89MX1sPSys3P
192.168.16.55,master,oz1XBUTK,89MX1sPSys3P
192.168.16.252,master,oz1XBUTK,89MX1sPSys3P
192.168.16.22,master,oz1XBUTK,sWr9MyYo
192.168.16.240,master,xP57KLXu,89MX1sPSys3P
192.168.16.18,master,xP57KLXu,sWr9MyYo
192.168.16.239,master,xP57KLXu,sWr9MyYo
192.168.8.26,master,xP57KLXu,89MX1sPSys3P
192.168.8.33,master,xP57KLXu,89MX1sPSys3P
192.168.32.132,master,xP57KLXu,sWr9MyYo
192.168.32.79,master,xP57KLXu,sWr9MyYo
192.168.32.21,master,oz1XBUTK,89MX1sPSys3P
192.168.32.22,master,oz1XBUTK,89MX1sPSys3P
192.168.32.55,master,oz1XBUTK,89MX1sPSys3P
192.168.32.44,master,xP57KLXu,sWr9MyYo
192.168.32.205,master,xP57KLXu,89MX1sPSys3P
192.168.32.204,master,oz1XBUTK,89MX1sPSys3P
192.168.32.60,master,xP57KLXu,sWr9MyYo
192.168.8.21,master,xP57KLXu,89MX1sPSys3P
192.168.32.111,master,xP57KLXu,89MX1sPSys3P
Onde: master é o usuário comum, e a última coluna, é a senha do usuário root

Notas

Algumas observações importantes acerca dos scripts, principalmente relacionado ao expect.

Nota

O script não sabe como lidar com verificação de certificado para servidores que ainda não estão na lista~/.ssh/known_hosts, portanto, para o script funcionar a contento, adicione essas duas linhas no arquivo~/.ssh/config
Arquivo ~/.ssh/config
Host *
StrictHostKeyChecking no

Nota

Em todos os hosts, o shell padrão do usuário comum e do root é o bash ou o sh.
Se você utiliza o csh deverá adaptar o arquivo daylight.exp na linha 23, onde ele espera o caracter que é do bash e do sh, e substituir por .
O timeout do expect está em -1, ou seja, se algum erro acontecer o expect congelará e é possível sair do processo spawned com Ctrl+C, verifique onde o script parou e faça os ajustes.

Comentários

Postagens mais visitadas