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

500px-Timezones2008_UTC-4Para 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 arquivo servidores.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 1

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 2

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.

Be Sociable, Share!
 banner ad
%d bloggers like this: