web-dev-qa-db-ja.com

Ansibleでソフトウェアバージョンを確認するにはどうすればよいですか?

私は3台のLinuxサーバーを持っており、ansibleインベントリファイルを作成しました。

[web]
192.168.0.155
192.168.0.165
192.168.0.175

そして、私は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' }

スクリプト(beer.py、vodka.py、whisky.py)は、バージョンを "/home/beer.py 1.0.0"のような形式で出力します。そして、私はこのバージョンを取得し、データベースに保存しているバージョン(これは実際のバージョンです)と比較する必要があります。バージョンが等しくない場合は、実際のバージョンをsvn(データベースにも保存されているsvnパス)からサーバーにコピーします。 ansible機能を使用してそれを行うにはどうすればよいですか?

4
Ivan Denisovich

Ansibleには、プログラムのバージョンを直接チェックするモジュールがありません。スクリプトの出力からバージョン番号を抽出するbashコマンドを含む2つのオプションがあります。これはおそらく行うはずです:

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

オプション1:タスクを実行してバージョンを取得します。基本的には、すでに持っているものとバージョン抽出です。

- 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

これで、変数versionsが登録され、versions.resultには、sw_pathと各ループ項目の戻り値を含む辞書のリストが含まれます。

このようなもの:

"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"
  }
}

登録されたデータの実際のコンテンツを表示するには、次のようなデバッグタスクを使用します。

- debug: var=versions

オプション2:カスタムファクトを使用

バージョンを返すスクリプトをリモートホストに(もちろんAnsibleを使用して)インストールできます。 Ansibleがこれらのホストに接続すると、他のシステムプロパティと同様に、これらのスクリプトが自動的に実行され、ファクトとして使用されます。

ローカルファクトのドキュメントは次のとおりです。

スクリプトは次のように単純なものにすることができます。

#!/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)

出力は次のようになります。

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

このスクリプトは、テンプレートモジュールなど、Ansibleを使用してインストールできます。そのため、sw_pathアイテムのリストに基づいて動的にすることもできます。

インストール後、ファクトをリロードする必要があります。テンプレートタスクの直後に、このタスクを使用してこれを行うことができます。

- setup:
    filter: ansible_local

これで、ansible_local.versions.beerなどのバージョンに直接アクセスできるようになります。

バージョンの検出についてはこれで終わりです。

あなたはそれについて言及しませんでしたが、比較のためにデータベースからバージョンを取得する方法を知っていると思います。それ以外の場合は、より多くのデータを提供する必要があります。それでは、「すべきバージョン」がshould["beer"]should["vodka"]、およびshould["whiskey"]として保存されていると仮定しましょう。

version_compare フィルターを使用してバージョンを比較できるようになりました。

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

これはアップグレードするだけですが、データベースで参照されているよりも新しいバージョンがインストールされている場合はダウングレードしません。もちろん、文字列を直接比較して、常に正確なバージョンをインストールすることを確認できます。

when: "{{ ansible_local.versions[item] != should[item] }}"
7
udondan