code

패키지가 설치되지 않은 경우 Ansible이 셸 스크립트를 실행하도록하는 방법

codestyles 2021. 1. 5. 08:07
반응형

패키지가 설치되지 않은 경우 Ansible이 셸 스크립트를 실행하도록하는 방법


(rpm) 패키지가 설치되지 않은 경우 Ansible이 쉘 스크립트를 실행하도록하려면 어떻게해야합니까? 어떻게 든 yum 모듈을 활용할 수 있습니까?


이 경우 yum 모듈이 도움이 될 것이라고 생각하지 않습니다. 현재는 부재, 현재, 최신의 3 가지 상태가 있습니다. 패키지를 실제로 설치하거나 제거하고 싶지 않은 것 같기 때문에 (적어도이 시점에서는) 두 가지 수동 단계로이 작업을 수행해야합니다. 첫 번째 작업은 패키지가 있는지 확인한 다음 두 번째 작업은 첫 번째 명령의 출력을 기반으로 명령을 호출합니다.

"rpm -q"를 사용하여 패키지가 있는지 확인하면 존재하는 패키지에 대한 출력은 다음과 같습니다.

# rpm -q httpd
httpd-2.2.15-15.el6.centos.1.x86_64

패키지가없는 경우 다음과 같이합니다.

# rpm -q httpdfoo
package httpdfoo is not installed

따라서 ansible 작업은 다음과 같습니다.

- name: Check if foo.rpm is installed
  command: rpm -q foo.rpm
  register: rpm_check

- name: Execute script if foo.rpm is not installed
  command: somescript
  when: rpm_check.stdout.find('is not installed') != -1

rpm 명령은 패키지가있는 경우 0으로 종료되고 패키지가 없으면 1로 종료되므로 다른 가능성은 다음을 사용하는 것입니다.

when: rpm_check.rc == 1

위의 Bruce P 답변에 따라 apt / deb 파일에 대한 유사한 접근 방식은 다음과 같습니다.

- name: Check if foo is installed
  command: dpkg-query -l foo
  register: deb_check

- name: Execute script if foo is not installed
  command: somescript
  when: deb_check.stdout.find('no packages found') != -1

이것과 관련이 있습니다.

모든 것을 모아서 Debian(Ubuntu)에 대한 완전한 플레이 북 이 이미 설치된 경우에만 패키지를 업데이트합니다.

---
- name: Update package only if already installed (Debian)
  hosts: all
  sudo: yes
  tasks:
    - name: Check if Package is installed
      shell: dpkg-query -W -f='${Status}' {{ package }} | grep 'install ok installed'
      register: is_installed
      failed_when: no
      changed_when: no

    - name: Update Package only if installed
      apt:
        name: {{ package }}
        state: latest
        update_cache: yes
      when: is_installed.rc == 0

안타깝게도 Ansible은 여전히 ​​간단한 패키지 업데이트를 지원하지 않습니다. 예 : https://github.com/ansible/ansible/issues/10856


시스템 패키지 관리자 (yum, apt 등) 자체를 통해 패키지를 설치할 수있는 경우 ansible의 체크 모드 플래그를 사용하여 실제로 패키지를 설치하지 않고도 설치 상태를 등록 할 수 있습니다.

- name: check if package is installed
  package:
    name: mypackage
    state: present
  check_mode: true
  register: mypackage_check

- name: run script if package installed
  shell: myscript.sh
  when: not mypackage_check.changed 

Ansible 2.5부터 package_facts 모듈을 사용할 수 있습니다 .

- name: Gather package facts
  package_facts:
    manager: auto

- name: Debug if package is present
  debug:
    msg: 'yes, mypackage is present'
  when: '"mypackage" in ansible_facts.packages'

- name: Debug if package is absent
  debug:
    msg: 'no, mypackage is absent'
  when: '"mypackage" not in ansible_facts.packages'

Note: you need the python bindings for apt/rpm installed on the target, e.g. python-apt for Debian.


You shouldn't be using dpkg -l package because it has no idea if your package has been removed or is still installed.
Instead it's probably better to use dpkg -s package.

To check if the package is installed :
- shell: dpkg -s package | grep 'install ok installed'
or if you don't mind the package on hold or other states :
- shell: dpkg -s package | grep 'installed'
This return 0 when installed and 1 if not.

(It's important to use the shell as we are using a pipe |)


I find using shell or command module is not "ansiblic".

I prefer to use yum module and json_query filter to check if a package is already installed. E.g. httpd package :

    - yum:
        list: httpd
      register: apache_service

    - assert:
        that:
          - "'installed' in apache_service|json_query('results[*].yumstate')"
      msg: 'httpd is not installed'

ReferenceURL : https://stackoverflow.com/questions/21892603/how-to-make-ansible-execute-a-shell-script-if-a-package-is-not-installed

반응형