Как заставить мой скрипт ждать, если запущен другой экземпляр APT? [закрыто]

Я столкнуться с некоторыми проблемами с моими скриптами.

Короче говоря, я прохожу стажировку, и мой босс дал мне задание сделать Зонд для Нагиоса.
Цель этого Зондирования - проверить на всех наших хостах, отсутствует ли пакет в репозитории, если да, то у нас есть предупреждение Nagios со списком отсутствующих пакетов.
Этот зонд может включать белый список, если мы хотим сохранить пакет, которого нет в каком-либо репо, но мы его не используем.

Вот мой сценарий:

#!/bin/bash

STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2

which apt-show-versions >/dev/null
STATE=$?

declare -a WHITELIST=( host1:elasticsearch:all host2:elasticsearch:all)
PACKAGES=()
NOT_AVAILABLE=()
HOST=$(hostname)


#while [ -f /var/lib/apt/lists/lock ]
#do
#  sleep 2
#done


if [ "$STATE" = 0 ] #Verifie la condition apt-show-version = installer
then

    packets=$(apt-show-versions | grep 'No available version in archive' | cut -d" " -f1)

    for packet in $packets;do
        PACKAGES+=("${HOST}:$packet")
    done

    for package in "${PACKAGES[@]}"; do
        if [ "${WHITELIST[*]}" != "${package}" ]; then
            NOT_AVAILABLE+=("$package")
        fi
    done

    if [ -z "$NOT_AVAILABLE" ]; then
        #Ok dans Nagios
        echo "There is no package without version in archive"
        exit $STATE_OK
    else
        #Warning dans Nagios
        echo "Some package have no available version in archive"
        echo ${NOT_AVAILABLE[*]//"${HOST}":}
        exit $STATE_WARNING
    fi
else
    #Critical dans nagios
    echo "Package apt-show-versions is missing"
    exit $STATE_CRITICAL
fi

И от Nagios приходит сообщение:

Remote command execution failed: Failed to open file /var/lib/apt/lists//security.debian.org_dists_stretch_updates_InRelease for reading: Permission denied

Я попытался поиграть с файлом блокировки в моем сценарии, но это не сработало, я получил бесконечный цикл.

Я уже рассматривал этот вопрос и пытался сделать обертку, но он не работал, или я что-то пропустил, так как я студент, и это мой первый шаг в мир сценариев оболочки.

Я тоже смотрел на , на этот , но он староват.

РЕДАКТИРОВАТЬ: Я нашел, как это сделать. Большое спасибо всем, кто пытается мне помочь, и особенно Сергею Колодяжному.

Я использовал APT и DPkg Hooks для этого, и мне пришлось изменить свой скрипт, чтобы использовать это крючки.

Я создаю файл с именем 00apt-show-version в /etc/apt/apt.conf.d / с этими двумя строками:

APT::Update::Post-Invoke {"apt-show-versions 1>/tmp/nagios_apt_show_versions";};
DPkg::Post-Invoke {"apt-show-versions 1> /tmp/nagios_apt_show_versions";}

Каждый раз, когда вызывается apt-get update или apt-get install / remove, apt-show-versions выполняет свою работу, и весь стандартный вывод apt-show-версий записывается в nagios_apt_show_versions.

После этого мне пришлось изменить свой сценарий следующим образом:

#!/bin/bash
#Script qui verifie si les paquets installer sur une machine ne dispose
#pas de versions dans les depots.


STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2

which apt-show-versions >/dev/null
STATE=$?

declare -a WHITELISTHOST=(host1:elasticsearch:all host2:elasticsearch:all host2:linux-image-4.9.0-0.bpo.5-amd64:amd64 host3:python-django-flatpages-tinymce:all)
WHITELIST=()
NOT_AVAILABLE=()
HOST=$(hostname)



if [ "$STATE" = 0 ]; then #Verifie la condition apt-show-version = installer

    #Verifie que le fichier n existe pas et le cree
    if [ ! -f "/tmp/nagios_apt_show_versions" ]; then
        touch /tmp/nagios_apt_show_versions
    fi

    packets=$(grep 'No available version in archive' /tmp/nagios_apt_show_versions | cut -d: -f1)


    for white in "${WHITELISTHOST[@]}"; do
        if [ "${HOST}" = "$(echo $white | cut -d: -f1)" ]; then
            WHITELIST+=("$(echo $white | cut -d: -f2)")
        fi
    done

    for packet in $packets; do
        if [ "${WHITELIST[@]}" != "${packet}" ]; then
            NOT_AVAILABLE+=("$packet")
        fi
    done

    if [ -z "$NOT_AVAILABLE" ]; then
        #Ok dans Nagios
        echo "There is no package without version in archive"
        exit $STATE_OK
    else
        #Warning dans Nagios
        echo "Some package have no available version in archive"
        echo ${NOT_AVAILABLE[*]}
        exit $STATE_WARNING
    fi

else
    #Critical dans nagios
    echo "Package apt-show-versions is missing"
    exit $STATE_CRITICAL
fi

Кстати, Withelist теперь работает (ну вроде, но это не цель этой ветки, я просто спрашивал о хуках)

4
задан 14 February 2019 в 18:44

1 ответ

Рассмотреть использование lsof проверять, используется ли файл, как рекомендуется на связанном сообщении Serverfault. Вы могли сделать что-то вроде этого:

while [ "x$(lsof /var/lib/apt/lists/lock)" != "x" ] ; do
    # if lsof returns output, that means some apt task is running
    # wait 60 seconds and check again
    sleep 60
done

Другая команда была бы fuser (и по моему скромному мнению лучше, чем lsof). Согласно документации:

термофиксатор возвращает ненулевой код возврата, если ни к одному из указанных файлов не получают доступ или в случае фатальной ошибки. Если по крайней мере один доступ был найден, нуль возвратов термофиксатора.

Это означает, что можно полагаться на статус выхода в цикле, который делает синтаксис более хорошим:

while fuser /var/lib/apt/lists/lock > /dev/null ; do
    sleep 60
done

Идеально, вероятно, необходимо использовать fnctl() тип функции, чтобы видеть, заблокирован ли файл, или через C или через Python.

См. также:

4
ответ дан 1 December 2019 в 09:43

Другие вопросы по тегам:

Похожие вопросы: