Como posso verificar a versão do software com o Ansible?

3

Eu tenho três servidores linux e criei o arquivo de inventário ansible:

[web]
192.168.0.155
192.168.0.165
192.168.0.175

E eu tenho playbook.yml:

---
- hosts: web
  tasks:

  - name: Check drinks versions
    shell: "python3.4 {{ item.sw_path }} -v"
    sudo: yes
    with_items:
      - { sw_path: '/home/beer.py' }
      - { sw_path: '/home/vodka.py' }
      - { sw_path: '/home/whisky.py' }

Os scripts (beer.py, vodka.py e whisky.py) imprimem suas versões em formato como: "/home/beer.py 1.0.0". E eu preciso obter essas versões, compará-lo com versões que eu armazeno no banco de dados (isto é as versões reais) e se as versões não são iguais, copie uma versão real do svn (svn caminhos também armazenados no banco de dados) para o servidor. Como posso fazer isso usando recursos ansiosos?

    
por Ivan Denisovich 10.06.2016 / 11:01

1 resposta

6

O Ansible não possui um módulo para verificar diretamente as versões de qualquer programa. Você tem duas opções, ambas envolvendo um comando bash para extrair o número da versão da saída de seus scripts. Isso provavelmente deve fazer:

$program | rev | cut -d ' ' -f1 | rev

Opção 1: execute as tarefas para buscar a versão. Basicamente o que você já teve mais a extração de versão.

- name: Check drinks versions
  shell: "python3.4 {{ item.sw_path }} -v | rev | cut -d ' ' -f1 | rev"
  sudo: yes
  with_items:
    - { sw_path: '/home/beer.py' }
    - { sw_path: '/home/vodka.py' }
    - { sw_path: '/home/whisky.py' }
  register: versions

Agora você tem uma variável versions registrada e em versions.result é uma lista de dicts que contém o sw_path e o valor de retorno de cada item de loop.

Algo parecido com isto:

"results": [
  {
    "item": {
      "sw_path": "/home/beer.py"
    },
    "stdout": "1.0.0"
  },
  {
    "item": {
      "sw_path": "/home/vodka.py"
    },
    "stdout": "1.0.0"
  },
  {
    "item": {
      "sw_path": "/home/whiskey.py"
    },
    "stdout": "1.0.0"
  }
}

Para ver o conteúdo real dos dados registrados, use uma tarefa de depuração como:

- debug: var=versions

Opção 2: Use fatos personalizados

Você pode instalar um script nos hosts remotos (com Ansible, é claro), que retorna as versões. Quando o Ansible se conecta a esses hosts, ele executa esses scripts automaticamente e os utiliza como fatos, como qualquer outra propriedade do sistema.

Aqui estão os documentos para fatos locais.

O script pode ser tão simples assim:

#!/bin/sh
echo [versions]
echo beer=$(python3.4 /home/beer.py -v | rev | cut -d ' ' -f1 | rev)
echo vodka=$(python3.4 /home/vodka.py -v | rev | cut -d ' ' -f1 | rev)
echo whiskey=$(python3.4 /home/whiskey.py -v | rev | cut -d ' ' -f1 | rev)

A saída deve estar assim:

[versions]
beer=1.0.0
vodka=1.0.0
whiskey=1.0.0

Você pode instalar esse script com o Ansible, por exemplo, com o módulo de modelo. Assim, você pode até torná-lo dinâmico com base na sua lista de sw_path itens.

Após a instalação, você precisa recarregar os fatos. Você pode fazer isso com essa tarefa logo após a tarefa do modelo:

- setup:
    filter: ansible_local

Agora você poderá acessar diretamente as versões como ansible_local.versions.beer etc.

Tanto para detectar as versões.

Você não mencionou, mas presumo que saiba como obter a versão do banco de dados para comparação. Caso contrário, você precisaria fornecer muito mais dados. Portanto, vamos supor que você tenha as "versões do should" armazenadas como should["beer"] , should["vodka"] e should["whiskey"] .

Agora você pode comparar as versões com o filtro version_compare .

- subversion: dummy command installing {{ item }}
  with_items:
    - beer
    - vodka
    - whiskey
  when: "{{ ansible_local.versions[item] | version_compare(should[item], '<') }}"

Isso só atualizará, mas nunca fará o downgrade no caso de uma versão mais nova do que a referenciada em seu banco de dados estiver instalada. É claro que você pode comparar diretamente as strings e sempre instalar a versão exata.

when: "{{ ansible_local.versions[item] != should[item] }}"
    
por 11.06.2016 / 10:52