Ansible Extraとalternativesモジュールの話 | Ansible Advent Calendar2014

December 11, 2014 by Yudai Suzuki

この記事はAnsible Advent Calendar 2014 16日目の記事です。 前日は、piohoさんAnsible Galaxy にロールを登録してバージョン管理してみる(Aerospike構築Roleで)でした。

本エントリーでは、先日Ansible Extraのalternativesモジュールを使おうとして、最終的にやめた話について書きます。

Ansible Extraとは?

This repo contains a subset of ansible-modules with slightly lower use or priority than “core” modules.

All new modules should be submitted here, and have a chance to be promoted to core over time.

ansible/ansible-modules-extrasリポジトリのREADMEより引用

v1.8でCoreとExtraに分割されました。 Coreが優先的にメンテナンスされます。 新しいモジュールはExtraにまず登録され、使用頻度・必要性などによりCoreに昇格されます。

AdventCalendar1日目、volanjaさん今年1年間でAnsible界隈ではどのような変化が起こったのか。より引用。

Ansible Extraとは、Ansible Coreに登録されているモジュールよりも利用頻度、優先度が低いと判断されているモジュール群です。 新しく作成されたモジュールはまずこのリポジトリにプルリクをし、おそらくコミッタの判断を経て最終的にCoreに昇格されるのでしょう。 分かりやすく言うと2軍ですね。

ExtraはAnsibleバージョン1.7まではCoreのリポジトリで一緒に管理されていましたが、1.8からは別々のリポジトリに分かれ、submoduleとしてAnsible本体のリポジトリで管理されています。

alternativesモジュールについて

注意: 筆者はpythonを書いたことがないので、言ってることが間違ってる可能性があります。間違いがありましたら@nekogeruge_987までお手数ですがご指摘お願いします。

ここから本題なのですが、alternativesを使いたい状況があったのでモジュールを探してみた所下記のドキュメントに辿り着きました。

alternatives - Manages alternative programs for common commands

使ってみたらエラー吐きました。

$ ansible-playbook -i dev_hosts provisioning_test.yml
 
PLAY [test] *******************************************************************
 
GATHERING FACTS ***************************************************************
ok: [pro_test]
 
TASK: [agent/postfix | MTA change to postfix] *********************************
fatal: [pro_test] => failed to parse: SUDO-SUCCESS-grtqdpoqwzskgcjfiecurouhaywxelgq
Traceback (most recent call last):
  File "/home/ec2-user/.ansible/tmp/ansible-tmp-1415702504.53-4900359849119/alternatives", line 1486, in <module>
    main()
  File "/home/ec2-user/.ansible/tmp/ansible-tmp-1415702504.53-4900359849119/alternatives", line 122, in main
    check_rc=True
  File "/home/ec2-user/.ansible/tmp/ansible-tmp-1415702504.53-4900359849119/alternatives", line 1339, in run_command
    args = [ os.path.expandvars(os.path.expanduser(x)) for x in args ]
  File "/usr/lib64/python2.6/posixpath.py", line 251, in expanduser
    if not path.startswith('~'):
AttributeError: 'NoneType' object has no attribute 'startswith'
 
 
FATAL: all hosts have already failed -- aborting
 
PLAY RECAP ********************************************************************
           to retry, use: --limit @/Users/yudai/provisioning_test.retry
 
pro_test                   : ok=1    changed=0    unreachable=1    failed=0

発生当時の環境。

  • OSX 10.9.4
  • Ansible 1.7.2 (Homebrewでインストール)
  • Python 2.7.5 (OSXにデフォルトで入っているPythonを使用)
  • Ansible実行対象OS: AmazonLinux

playbookはこんな感じ。

---
- name: MTA change to postfix
  alternatives: name=mta path=/usr/sbin/sendmail.postfix

調査

結論から言うと

linkオプションを指定すれば使えます。

---
- name: MTA change to postfix
  alternatives: name=mta path=/usr/sbin/sendmail.postfix link=/usr/sbin/sendmail

shellモジュールでやるとこんな感じ

- name: MTA change to postfix
  shell: alternatives --set mta /usr/sbin/sendmail.postfix

ググる

同様の問題が発生しているissuesがありました。

ソースを読んでみる

この部分

Manages symbolic links using the ‘update-alternatives’ tool provided on debian-like systems.

なるほど、そもそもdebianしか想定してないってことですね。

pathで指定したコマンドがalternativesに無い場合、インストールしてます。その際、linkオプションの指定が必要になるわけですね。
でも無いから落ちてて、linkオプションがあるとちゃんとインストールされるからうまくいくってことかな。

1.8になってRedHat系OSも対応された模様

https://github.com/ansible/ansible-modules-extras/blob/devel/system/alternatives.py

あれ、--listオプションってRedHat系のOSのupdate-alternativesで使えましたっけ…ちょっとVagrant使って調べてみます。

  • CentOS6.5
[vagrant@vagrant-centos65 ~]$ update-alternatives --version
alternatives version 1.3.49.3
[vagrant@vagrant-centos65 ~]$ update-alternatives
alternatives version 1.3.49.3 - Copyright (C) 2001 Red Hat, Inc.
This may be freely redistributed under the terms of the GNU Public License.

usage: alternatives --install <link> <name> <path> <priority>
                    [--initscript <service>]
                    [--slave <link> <name> <path>]*
       alternatives --remove <name> <path>
       alternatives --auto <name>
       alternatives --config <name>
       alternatives --display <name>
       alternatives --set <name> <path>

common options: --verbose --test --help --usage --version
                --altdir <directory> --admindir <directory>
  • AmazonLinux release 2014.09
[ec2-user@ip-10-1-1-31 ~]$ update-alternatives --version
alternatives バージョン 1.3.49.3
[ec2-user@ip-10-1-1-31 ~]$ update-alternatives
alternatives バージョン 1.3.49.3 - Copyright (C) 2001 Red Hat, Inc.
これは GNU 一般公有使用許諾書の規定の元で自由に再配布することができます。

使用法: alternatives --install <リンク> <名前> <パス> <優先度>
                    [--initscript <サービス>]

                    [--slave <リンク> <名前> <パス>]*
       alternatives --remove <名前> <パス>
       alternatives --auto <名前>
       alternatives --config <名前>
       alternatives --display <名前>
       alternatives --set <名前> <パス>

共通のオプション: --verbose --test --help --usage --version
                --altdir <ディレクトリ> --admindir <ディレクトリ>
  • CentOS7
[vagrant@localhost ~]$ update-alternatives --version
alternatives バージョン 1.3.61
[vagrant@localhost ~]$ update-alternatives
alternatives バージョン 1.3.61 - Copyright (C) 2001 Red Hat, Inc.
これは GNU 一般公有使用許諾書の規定の元で自由に再配布することができます。

使用法: alternatives --install <リンク> <名前> <パス> <優先度>
                    [--initscript <サービス>]

                    [--slave <リンク> <名前> <パス>]*
       alternatives --remove <名前> <パス>
       alternatives --auto <名前>
       alternatives --config <名前>
       alternatives --display <名前>
       alternatives --set <名前> <パス>
       alternatives --list

共通のオプション: --verbose --test --help --usage --version
                --altdir <ディレクトリ> --admindir <ディレクトリ>
  • Fedora20
[vagrant@vagrant-fedora20 ~]$ update-alternatives --version
alternatives バージョン 1.3.60
[vagrant@vagrant-fedora20 ~]$ update-alternatives
alternatives バージョン 1.3.60 - Copyright (C) 2001 Red Hat, Inc.
これは GNU 一般公有使用許諾書の規定の元で自由に再配布することができます。

使用法: alternatives --install <リンク> <名前> <パス> <優先度>
                    [--initscript <サービス>]

                    [--slave <リンク> <名前> <パス>]*
       alternatives --remove <名前> <パス>
       alternatives --auto <名前>
       alternatives --config <名前>
       alternatives --display <名前>
       alternatives --set <名前> <パス>
       alternatives --list

共通のオプション: --verbose --test --help --usage --version
                --altdir <ディレクトリ> --admindir <ディレクトリ>
  • Ubuntu14.04
vagrant@vagrant-ubuntu-trusty-64:~$ update-alternatives --version
Debian update-alternatives version 1.17.5.

This is free software; see the GNU General Public License version 2 or
later for copying conditions. There is NO warranty.
vagrant@vagrant-ubuntu-trusty-64:~$ update-alternatives
update-alternatives: need --display, --query, --list, --get-selections, --config, --set, --set-selections, --install, --remove, --all, --remove-all or --auto

Use 'update-alternatives --help' for program usage information.
  • Debian7.4
vagrant@vagrant-debian-wheezy:~$ update-alternatives --version
Debian update-alternatives version 1.16.12.

This is free software; see the GNU General Public License version 2 or
later for copying conditions. There is NO warranty.
vagrant@vagrant-debian-wheezy:~$ update-alternatives
update-alternatives: need --display, --query, --list, --get-selections, --config, --set, --set-selections, --install, --remove, --all, --remove-all or --auto

Usage: update-alternatives [<option> ...] <command>

Commands:
  --install <link> <name> <path> <priority>
    [--slave <link> <name> <path>] ...
                           add a group of alternatives to the system.
  --remove <name> <path>   remove <path> from the <name> group alternative.
  --remove-all <name>      remove <name> group from the alternatives system.
  --auto <name>            switch the master link <name> to automatic mode.
  --display <name>         display information about the <name> group.
  --query <name>           machine parseable version of --display <name>.
  --list <name>            display all targets of the <name> group.
  --get-selections         list master alternative names and their status.
  --set-selections         read alternative status from standard input.
  --config <name>          show alternatives for the <name> group and ask the
                           user to select which one to use.
  --set <name> <path>      set <path> as alternative for <name>.
  --all                    call --config on all alternatives.

<link> is the symlink pointing to /etc/alternatives/<name>.
  (e.g. /usr/bin/pager)
<name> is the master name for this link group.
  (e.g. pager)
<path> is the location of one of the alternative target files.
  (e.g. /usr/bin/less)
<priority> is an integer; options with higher numbers have higher priority in
  automatic mode.

Options:
  --altdir <directory>     change the alternatives directory.
  --admindir <directory>   change the administrative directory.
  --log <file>             change the log file.
  --force                  allow replacing files with alternative links.
  --skip-auto              skip prompt for alternatives correctly configured
                           in automatic mode (relevant for --config only)
  --verbose                verbose operation, more output.
  --quiet                  quiet operation, minimal output.
  --help                   show this help message.
  --version                show the version.

あー、alternativesのバージョンが古いと--listオプション使えないですね。CentOS6系とAmazonLinuxは注意が必要です。
そして--listオプションってDebianとRedHatのものだと全然動きが違うんですね。nameついてないよってプルリク送る所でした。

個人的に、ディストリビューション判定の部分が気になります。update-alternativesを叩いてReturn Code見てDebianかRedHatかの判定してます。 ansible_os_familyとか呼べないんですかね?この辺各モジュールごとの独自実装になっちゃったら大変な気がするんですが。

なおせるかなと思ってansible_os_family呼べるモジュールなりメソッドなりをCoreの方で探してみたんですが、ちょっと見つけられませんでした。
または、上記ディストリビューションでコマンド叩いて思ったのですが、update-alternativesはDebian製とRedHat製のものしか無いとか?だとしたらこれでもまあいいのかな。

あとちょっと思ったのは、モジュールの方でディストリビューション判別してくれるのは助かるんですけど、例えばansibleってyumaptでモジュールが異なっているので、こういう場合はモジュールをディストリビューション毎に分けて、playbook書く側が分けて使うほうがansibleの設計思想にあってるんじゃないかなと思ったりしました。

まあでもこれはコマンド一緒だし、物によるか。識者からご意見いただけると幸いです。

何が言いたいか

こんな感じで、Extraモジュールを使う際には(当たり前ですが)注意が必要です。 筆者は知らずに使ってしまったのでちょっと嵌りました。alternativesモジュールに関しては、まだshellで対応する方がいい気がします。

Ansible Extraに関してはまだ日本語記事が少なかったので今回の記事を書いてみました。 逆に言えば、Contributeのチャンスがありそうということですね。

僕はこう思ったっス

ちゃんと読まなかった自分が悪いんですが、このページは少しわかりづらいかなと思いました。 This is an Extras Module のくだりは上の方にあってもいいんじゃないっすかね。

明日はtnayukiさんです。

© 2017 | Onigra | Powerd by Hucore theme & Hugo