De acordo com decreto nº 9772/2019 assinado pelo atual presidente da república não teremos mais horário de verão no Brasil e independente de gostar ou não da mudança ela esta ai e temos que agir para resolver os problemas que ela vai gerar (e que bom que mudanças geram problemas isso garante nossos empregos). O procedimento descrito aqui foi validado em algumas máquinas Linux com Debian, Ubuntu e CentOS mas possivelmente atende a outras distribuições com algum ajuste.
Vai ou não vai virar?
Para saber se o seu servidor vai virar para o horário de verão ou não, podemos usar o comando “zdump” que acompanha o pacote “tzdata” na maioria das distribuições.
O exemplo abaixo é de um servidor que vai virar para o horário de verão agora em 3-novembro-2019 (observe as duas ultimas linhas da saída do comando)
# zdump -v /etc/localtime | grep 2019
/etc/localtime Sun Feb 17 01:59:59 2019 UTC = Sat Feb 16 23:59:59 2019 -02 isdst=1 gmtoff=-7200
/etc/localtime Sun Feb 17 02:00:00 2019 UTC = Sat Feb 16 23:00:00 2019 -03 isdst=0 gmtoff=-10800
/etc/localtime Sun Nov 3 02:59:59 2019 UTC = Sat Nov 2 23:59:59 2019 -03 isdst=0 gmtoff=-10800
/etc/localtime Sun Nov 3 03:00:00 2019 UTC = Sun Nov 3 01:00:00 2019 -02 isdst=1 gmtoff=-7200
Um sistema que não vai virar para o horário de verão (justamente o que nós queremos é o seguinte):
zdump -v /etc/localtime | grep 2019 /etc/localtime Sun Feb 17 01:59:59 2019 UTC = Sat Feb 16 23:59:59 2019 -02 isdst=1 gmtoff=-7200 /etc/localtime Sun Feb 17 02:00:00 2019 UTC = Sat Feb 16 23:00:00 2019 -03 isdst=0 gmtoff=-10800
Servidores novos e que ainda recebam atualizações de segurança de seus desenvolvedores certamente já possuem um pacote tzdata atualizado (provavelmente baseado nos pacotes oficiais 2009b ou 2019b) e teremos uma saída como a do segundo exemplo, porém quem ainda possui servidores rodando versões antigas de seus sistemas operacionais a saída será igual a do primeiro exemplo e solução é atualizar o tzdata manualmente.
O procedimento de atualização é simples e poderia ser feito de diversas maneiras diferentes. Eu optei pela mais simples e que usa apenas um comando para ser executado.
Uma vez que identifico uma máquina que entraria no horário de verão (vide comando zdump acima) eu simplesmente sobreescrevo o seu arquivo de timezone pelo de uma máquina atualizada que não teria o problema, usando ocomando “scp”, como abaixo:
root@servidorvelho# scp wbraga@meudesktop:/usr/share/zoneinfo/America/Sao_Paulo /usr/share/zoneinfo/America/Sao_Paulo
Perceba que eu copio diretamente o arquivo de timezone do meu desktop para o meu servidor problemático. Este arquivo é exatamente o mesmo para qualquer distribuição então não se preocupe de estar copiando de um Debian para um Ubuntu, CentOS ou Redhat, ou qualquer combinação.
A única atenção ai é copiar o timezone correto que neste meu caso é America/Sao_Paulo. Como última dica então, o arquivo “/etc/localtime” na verdade é um symlink para o arquivo correto de timezone da sua máquina. Um “ls-l /etc/timezone” vai te dar a dica de qual arquivo copiar.
A imagem acima mostra o procedimento completo executado diretamente em um servidor de produção sem impactos no ambiente.
Automatizando com Ansible
A playbook abaixo é bem rudimentar mas me atendeu bem para configurar pouco mais de uma centena de máquinas Linux usando uma única linha de comando. Se interessar copie e altere-a de acordo com sua necessidade.
--- - name: Atualiza timezone dos servidores Linux hosts: VM tasks: - name: Pega o link para o localtime stat: path: /etc/localtime register: arq - name: Copia o arquivo de Timezone para o zoneinfo become: yes copy: src: '{{ arq.stat.lnk_source }}' dest: '{{ arq.stat.lnk_source }}' backup: yes when: arq.stat.islnk - name: Copia o arquivo de Timezone para o Localtime become: yes copy: src: /etc/localtime dest: /etc/localtime backup: yes when: arq.stat.isreg
Nesta PB eu considero dois cenários: Distribuições mais recentes possuem o /etc/localtime como um link simbólico para o arquivo de zoneinfo correto dentro de /usr/share/zoneinfo. Já as mais antigas usam uma cópia deste mesmo arquivo.
Para executá-la e atualizar todo o seu ambiente basta usar a linha de comandos abaixo:
$ ansible-playbook -K atualizatimezone.yml