nakayumcの技術ブログ

エンジニア1年目のブログです。(旧ブログも混在してますが、こっちが新しいです)

yumモジュールのpresentとinstalledの違いを比べてみた

はじめに

お疲れ様です。 最近暑い日が続いて大変ですね。

さて、私は7月から配属となりました。
配属となった部署ではAnsibleを主に使っていて、現在、Ansibleについての研修を私と先輩、2人で受けています。

今回は、yum モジュールで git をインストールする Playbook の課題に取り組んでいました。

それぞれ完成したPlaybook を 2人で確認したら state の指定が presentinstalled で分かれました。

そこで私は、指定方法によってどのような違いがあるのか気になり、出力結果を比べてみたり、debugとかしてみました。(最終的にソースコードを覗きました)

間違っている箇所もあるかと思うので、なにか気になることがあったら@nakayumc0278 まで直接連絡いただければと思います。

TL;DR

  • 結果的には同じ動作をする
  • debug で確認しても同様の結果
  • ソースコード上で確認すると if state in ['installed', 'present']: となっており、 同じ動作をするようになっていた。
  • installed は present の Alias である。

環境

環境は下記の通りです。

  • サーバとか
名前 IPアドレス OS
control 192.168.1.110 RHEL 8.6
node01 192.168.1.111 CentOS 7
node02 192.168.1.112 CentOS 7
  • ansible バージョン
    (venv) ansible [core 2.12.1]

検証した Playbook と Inventory ファイル

今回検証に使った Playbook です。

---
- hosts: node01
  gather_facts: false
  become: true

  tasks:
    - name: install git
      ansible.builtin.yum:
        name: git
        state: <present or installed>

inventory ファイルはこんな感じです。

[sv]
node01 ansible_host=192.168.1.111
node02 ansible_host=192.168.1.112

[sv:vars]
ansible_user=ansible
ansible_password=ansible
ansible_become=yes
ansible_become_password=ansible

実際に実行してみる

最初、state: present で実行します。

$ ansible-playbook -i inventory.ini install_git.yml
PLAY [node01] ***********************************************************************************
TASK [install git] ******************************************************************************
changed: [node01]
PLAY RECAP **************************************************************************************
node01                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

次に、state: installed に変更し、実行します。

$ ansible-playbook -i inventory.ini install_git.yml
PLAY [node01] ***********************************************************************************
TASK [install git] ******************************************************************************
changed: [node01]
PLAY RECAP **************************************************************************************
node01                     : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

どちらもgitパッケージをインストールできました。

ansible-playbook コマンドの -vvv オプションで見てみる

Playbook上で、state: presentに変更してデバッグオプションを入れて(-vvv)実行すると、が"state": "present"になっていることが確認できました。

$ ansible-playbook -i inventory.ini install_git.yml -vvv
changed: [node01] => {
    ・・・
    },
    "invocation": {
        "module_args": {
            "allow_downgrade": false,
             ・・・
            "skip_broken": false,
            "state": "present",
            "update_cache": false,
        }

今度はPlaybook上をstate: installedに変更して実行した結果、"state": "installed"になっていることが確認できました。

$ ansible-playbook -i inventory.ini install_git.yml -vvv
changed: [node01] => {
    ・・・
    },
    "invocation": {
        "module_args": {
            "allow_downgrade": false,
             ・・・
            "skip_broken": false,
            "state": "installed",
            "update_cache": false,
        }

結果としては、stateの部分が変わっただけで、これといって特に大きな変更は見当たりませんでした。

yumモジュールのソースコードを見てみた

ソースコード上ではどのように動作しているのか、githubで公開されているyumモジュールのソースコードを確認してみました。

github.com

すると、1645行目あたりに記述がありました。

        if self.state == 'latest' or self.update_only:
            if self.disable_gpg_check:
                self.yum_basecmd.append('--nogpgcheck')
            if self.security:
                self.yum_basecmd.append('--security')
            if self.bugfix:
                self.yum_basecmd.append('--bugfix')
            res = self.latest(pkgs, repoq)
        elif self.state in ('installed', 'present'):
            if self.disable_gpg_check:
                self.yum_basecmd.append('--nogpgcheck')
            res = self.install(pkgs, repoq)
        elif self.state in ('removed', 'absent'):
            res = self.remove(pkgs, repoq)

上記のコードの9行目あたりにある、elif self.state in ('installed', 'present'): ですが、if文で書かれていて、ここにstateinstalled と present は同様の動作をするように書かれています。
他にも、stateremoved と absentどちらを指定しても、パッケージ削除の動作をしています。

まとめ

まとめると以下のようになります。

  • yum モジュール の state を present と installed は同じ動作をする
  • debug で確認しても同様の結果だった。
  • ソースコード上で確認すると if state in ['installed', 'present']: となっており、
    同じ動作をするようになっていた。
  • installed は present の Alias である。

ということが確認できました。