Как удалить пакеты из моего собственного пакета Debian?

Я знаю основы создания пакета Debian. Но я хочу создать такой, который будет помечать другие пакеты для удаления по мере их установки.

В папке Debian пакета в контрольном файле я попытался поместить пакеты, которые я хочу удалить, в поле Conflicts or Breaks, но безуспешно. apt-get отказывается устанавливать мой пакет и не удаляет пакеты ни в конфликтах, ни в перерывах ...

Чего мне не хватает? Не удалось найти соответствующие инструкции в руководствах Debian ...

2
задан 3 August 2013 в 01:58

1 ответ

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

  1. Отключите временно apt/dpkg блокировки
  2. Программное обеспечение Update / Install / Remove
  3. Слияние изменяется на dpkg базу данных
  4. Включите назад apt/dpkg блокировки
  5. Прибыль

1. Отключите временно apt/dpkg блокировки

Переместите временно в другое местоположение следующие файлы:

  • /var/lib/dpkg/lock
  • /var/lib/dpkg/updates/
  • /var/cache/apt/archives/lock

2. Программное обеспечение Update / Install / Remove

Выполненная Кв. - добирается, чтобы установить/удалить программное обеспечение, Подтвердить, что apt-get/dpkg пишут его состояние в:

  • /var/lib/dpkg/status

Давайте предположим, что у Вас есть система со следующими пакетами: firefox, htop, curl, и давайте предположим что Ваш пакет foo удаляет curl, таким образом на установку Вашего пакета Вы должны иметь firefox, htop, foo однако, так как dpkg обновляет свое состояние однажды на экземпляр, Ваше вложенное состояние будет overrided родительским процессом, оставляя следующее состояние firefox, htop, curl, foo

Так, у Вас не будет вихревых файлов вокруг, но к dpkg будет все еще установлен пакет, это также произойдет с новым программным обеспечением и зависимостями.

Давайте предположим Ваш foo установки пакетов apache2 который зависит в apache2-data, Вы ожидали бы их в своей dpkg базе данных как: firefox, htop, curl, foo, apache2, apache2-data , однако Вы будете иметь firefox, htop, curl, foo, вложенный вывод был overrided родительским процессом, который только знал об установке foo

3. Слияние изменяется на dpkg базу данных

Для предотвращения этой путаницы необходимо будет заботиться об изменениях dpkg вручную, также так как файл является overrided с другими apt-get/dpkg экземплярами, необходимо было бы сохранить изменения в другом месте и применить их к исходному файлу только после того, как основной apt-get/dpkg экземпляр будет сделан, так как сценарий закончится, прежде чем это происходит, необходимо будет оставить позади cronjob запись или демона ручной работы.

4. Включите назад apt/dpkg блокировки

5. Прибыль

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

package=my-pkg

_dpkg_suspend_process() {
    #unlock standard files
    busybox mv     /var/lib/dpkg/lock           /var/lib/dpkg/lock.suspended
    busybox rm -rf /var/lib/dpkg/updates.suspended/
    busybox mv     /var/lib/dpkg/updates/       /var/lib/dpkg/updates.suspended
    busybox mkdir  /var/lib/dpkg/updates/
    busybox mv     /var/cache/apt/archives/lock /var/cache/apt/archives/lock.suspended

    #debconf missing file descriptors workaround
    busybox cp /usr/share/debconf/confmodule       /usr/share/debconf/confmodule.bk  
    busybox cp /usr/share/minos/debconf/confmodule /usr/share/debconf/confmodule

    #while apt is being executed it modifies the status file which brings conflicts
    #to new packages if they're installed/removed in abused apt instances, therefore
    #the status-old file (which represent the original state in which the first
    #apt instance was launched) is used to create temporal diffs which will be merged
    #at the end
    busybox cp     /var/lib/dpkg/status         /var/lib/dpkg/status.suspended
    busybox cp     /var/lib/dpkg/status-old     /var/lib/dpkg/status-orig
    busybox cp     /var/lib/dpkg/status-orig    /var/lib/dpkg/status
}

_dpkg_continue_process() {
    #relock standard files
    busybox rm -rf /var/lib/dpkg/updates
    busybox mv     /var/lib/dpkg/lock.suspended           /var/lib/dpkg/lock
    busybox mv     /var/lib/dpkg/updates.suspended        /var/lib/dpkg/updates
    busybox mv     /var/cache/apt/archives/lock.suspended /var/cache/apt/archives/lock
    busybox mv     /var/lib/dpkg/status.suspended         /var/lib/dpkg/status

    #debconf missing file descriptors workaround
    busybox mv     /usr/share/debconf/confmodule.bk       /usr/share/debconf/confmodule

    #keep status-old file to survive multiple abused apt instances
    busybox mv     /var/lib/dpkg/status-orig              /var/lib/dpkg/status-old
}

_dpkg_sync_status_db() {
    _dpkg_sync_status_db_script="/var/lib/dpkg/dpkg-sync-status-db"
    _dpkg_sync_status_db_script_generator() {
        printf "%s\\n" "#!/bin/sh"
        printf "%s\\n" "#autogenerated by ${package}: $(date +%d-%m-%Y:%H:%M)"
        printf "\\n"
        printf "%s\\n" '##close stdout'
        printf "%s\\n" '#exec 1<&-'
        printf "%s\\n" '##close stderr'
        printf "%s\\n" '#exec 2<&-'
        printf "%s\\n" '##open stdout as $log_file file for read and write.'
        printf "%s\\n" "#exec 1<> /tmp/${package}.\${$}.debug"
        printf "%s\\n" '##redirect stderr to stdout'
        printf "%s\\n" '#exec 2>&1'
        printf "%s\\n" '#set -x #enable trace mode'
        printf "\\n"
        printf "%s\\n" "while fuser /var/lib/dpkg/lock >/dev/null 2>&1; do sleep 1; done"
        printf "\\n"
        printf "%s\\n" 'pkgs__add="$(cat /var/lib/apt/apt-add-queue)"'
        printf "%s\\n" 'if [ -n "${pkgs__add}" ]; then'
        printf "%s\\n" '  for pkg in $pkgs__add; do'
        printf "%s\\n" '    if ! busybox grep "^Package: ${pkg}$" /var/lib/dpkg/status >/dev/null 2>&1; then'
        printf "%s\\n" '      busybox sed -n "/Package: ${pkg}$/,/^$/p" \'
        printf "%s\\n" "      /var/lib/dpkg/status-append-queue >> /var/lib/dpkg/status"
        printf "%s\\n" "    fi"
        printf "%s\\n" "  done"
        printf "%s\\n" "fi"
        printf "\\n"
        printf "%s\\n" 'pkgs__rm="$(cat /var/lib/apt/apt-rm-queue)"'
        printf "%s\\n" 'if [ -n "${pkgs__rm}" ]; then'
        printf "%s\\n" '  for pkg in $pkgs__rm; do'
        printf "%s\\n" '    busybox sed -i "/Package: ${pkg}$/,/^$/d" /var/lib/dpkg/status'
        printf "%s\\n" "  done"
        printf "%s\\n" "fi"
        printf "\\n"
        printf "%s\\n" "mv /var/lib/apt/apt-add-queue /var/lib/apt/apt-add-queue.bk"
        printf "%s\\n" "mv /var/lib/apt/apt-rm-queue  /var/lib/apt/apt-rm-queue.bk"
        printf "%s\\n" "mv /var/lib/dpkg/status-append-queue /var/lib/dpkg/status-append-queue.bk"
        printf "\\n"
        printf "%s\\n" "rm -rf /var/lib/apt/apt-add-queue /var/lib/apt/apt-rm-queue"
        printf "%s\\n" "rm -rf ${_dpkg_sync_status_db_script}"
    }

    _dpkg_sync_status_db_script_generator > "${_dpkg_sync_status_db_script}"
    chmod +x "${_dpkg_sync_status_db_script}"
    _daemonize /bin/sh -c "${_dpkg_sync_status_db_script}"
}

_daemonize() {
    #http://blog.n01se.net/blog-n01se-net-p-145.html
    [ -z "${1}" ] && return 1
    (   #1. fork, to guarantee the child is not a process
        #group leader, necessary for setsid) and have the
        #parent exit (to allow control to return to the shell)

        #2. redirect stdin/stdout/stderr before running child
        [ -t 0 ] && exec  </dev/null
        [ -t 1 ] && exec  >/dev/null
        [ -t 2 ] && exec 2>/dev/null
        if ! command -v "setsid" >/dev/null 2>&1; then
            #2.1 guard against HUP and INT (in child)
            trap '' 1 2
        fi

        #3. ensure cwd isn't a mounted fs so it does't block
        #umo unt invocations
        cd /

        #4. umask (leave this to caller)
        #umask 0

        #5. close unneeded fds
        #XCU 2.7 Redirection says: open files are represented by
        #decimal numbers starting with zero. The largest possible
        #value is implementation-defined; however, all
        #implementations shall support at least 0 to 9, inclusive,
        #for use by the application.
        i=3; while [ "${i}" -le "9" ]; do
            eval "exec ${i}>&-"
            i="$(($i + 1))"
        done

        #6. create new session, so the child has no
        #controlling terminal, this prevents the child from
        #accesing a terminal (using /dev/tty) and getting
        #signals from the controlling terminal (e.g. HUP, INT)
        if command -v "setsid" >/dev/null 2>&1; then
            exec setsid "$@"
        elif command -v "nohup" >/dev/null 2>&1; then
            exec nohup "$@" >/dev/null 2>&1
        else
            if [ ! -f "${1}" ]; then
                "$@"
            else
                exec "$@"
            fi
        fi
    ) &
    #2.2 guard against HUP (in parent)
    if ! command -v "setsid" >/dev/null 2>&1 \ &&
       ! command -v "nohup"  >/dev/null 2>&1; then
        disown -h "${!}"
    fi
}

_apt_add_queue() {
    for pkg in "${@}"; do
        if  busybox grep "${pkg}" /var/lib/apt/apt-rm-queue >/dev/null 2>&1; then
            busybox sed -i "/^${pkg}$/d" /var/lib/apt/apt-rm-queue
        else
            if ! busybox grep "^Package: ${pkg}$" /var/lib/dpkg/status >/dev/null 2>&1; then
                printf "%s\\n" "${pkg}" >> /var/lib/apt/apt-add-queue
            fi
        fi
    done; unset pkg
}

_apt_rm_queue() {
    for pkg in "${@}"; do
        if  busybox grep "${pkg}" /var/lib/apt/apt-add-queue >/dev/null 2>&1; then
            busybox sed -i "/^${pkg}$/d" /var/lib/apt/apt-add-queue
        else
            if busybox grep "^Package: ${pkg}$" /var/lib/dpkg/status >/dev/null 2>&1; then
                printf "%s\\n" "${pkg}" >> /var/lib/apt/apt-rm-queue
            fi
        fi
    done; unset pkg
}

_apt_install() {
    [ -z "${1}" ] && return
    _apt_add_queue $(printf "%s\\n" "${@}" | busybox sed "s:${package}::g")
}

_apt_purge() {
    [ -z "${1}" ] && return
    _apt_rm_queue $(printf "%s\\n" "${@}" | busybox sed "s:${package}::g")
}

_apt_run() {
    [ ! -f /var/lib/apt/apt-add-queue ] && [ ! -f /var/lib/apt/apt-rm-queue ] && return

    pkgs__add="$(cat /var/lib/apt/apt-add-queue 2>/dev/null)"
    if [ -n "${pkgs__add}" ]; then
        _dpkg_suspend_process
        busybox awk '/^Package: /{print $2}' /var/lib/dpkg/status | \
            busybox sort > /var/lib/dpkg/status-pkgs.orig
        _apt_run__output="$(DEBIAN_FRONTEND=noninteractive apt-get install  \
            --no-install-recommends -y -o Dpkg::Options::="--force-confdef" \
            -o Dpkg::Options::="--force-confold" --force-yes ${pkgs__add} 2>&1)" || \
            printf "%s\\n" "${_apt_run__output}" >&2
        busybox awk '/^Package: /{print $2}' /var/lib/dpkg/status | \
            busybox sort > /var/lib/dpkg/status-pkgs.current
        _dpkg__added_pkgs="$(busybox diff -Naur /var/lib/dpkg/status-pkgs.orig \
            /var/lib/dpkg/status-pkgs.current | busybox awk '/^\+[a-zA-Z]/{gsub("^+","");print;}')"
        busybox rm -rf /var/lib/dpkg/status-pkgs*
        #add dependencies
        if [ -n "${_dpkg__added_pkgs}" ]; then
            printf "%s\\n" "${_dpkg__added_pkgs}" >> /var/lib/apt/apt-add-queue
            printf "%s\\n" "$(busybox sort /var/lib/apt/apt-add-queue | busybox uniq)" \
                > /var/lib/apt/apt-add-queue
        fi

        #extract dpkg status output to append it at the end
        for pkg in $_dpkg__added_pkgs; do
            busybox sed -n '/Package: '"${pkg}"'$/,/^$/p' /var/lib/dpkg/status \
                >> /var/lib/dpkg/status-append-queue
        done
        _dpkg_continue_process
    fi

    pkgs__rm="$(cat /var/lib/apt/apt-rm-queue 2>/dev/null)"
    if [ -n "${pkgs__rm}" ]; then
        _dpkg_suspend_process
        busybox awk '/^Package: /{print $2}' /var/lib/dpkg/status | \
            busybox sort > /var/lib/dpkg/status-pkgs.orig
        _apt_run__output="$(DEBIAN_FRONTEND=noninteractive apt-get purge \
            -y ${pkgs__rm} 2>&1)" || printf "%s\\n" "${_apt_run__output}" >&2
        busybox awk '/^Package: /{print $2}' /var/lib/dpkg/status | \
            busybox sort > /var/lib/dpkg/status-pkgs.current
        _dpkg__removed_pkgs="$(busybox diff -Naur /var/lib/dpkg/status-pkgs.orig \
            /var/lib/dpkg/status-pkgs.current | busybox awk '/^-[a-zA-Z]/{gsub("^-","");print;}')"
        busybox rm -rf /var/lib/dpkg/status-pkgs*
        #remove dependencies
        if [ -n "${_dpkg__removed_pkgs}" ]; then
            printf "%s\\n" "${_dpkg__removed_pkgs}" >> /var/lib/apt/apt-rm-queue
            printf "%s\\n" "$(busybox sort /var/lib/apt/apt-rm-queue | busybox uniq)" \
                > /var/lib/apt/apt-rm-queue
        fi
        _dpkg_continue_process
    fi

    _dpkg_sync_status_db
}

_apt_install foo bar
_apt_purge   ugly packages
_apt_run
0
ответ дан 3 August 2013 в 01:58

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

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