Làm thế nào để chạy tập lệnh chỉ trong lần cài đặt đầu tiên của gói và trong quá trình nâng cấp?


14

Gần đây tôi đã bắt đầu đóng gói một số phần mềm của mình và xuất bản nó trên Launchpad. Việc cài đặt và gỡ bỏ hoạt động tốt, nhưng việc nâng cấp gói một phiên bản lên phiên bản tiếp theo là có vấn đề.

Vấn đề là có một số tập lệnh chỉ cần chạy trong lần cài đặt đầu tiên của gói. Các tập lệnh này điền vào DB, tạo người dùng, v.v. Chúng hiện đang được gọi trong phần pack.postinst configure). Tuy nhiên, điều này dẫn đến việc chúng được gọi trong quá trình nâng cấp cũng như hiển thị trong sơ đồ .

Có cách nào để bao gồm tập lệnh bảo trì trong gói .deb chỉ thực thi trong lần cài đặt đầu tiên của gói chứ không phải trong quá trình nâng cấp không? Hoặc điều gì sẽ là một cách thanh lịch để bao gồm một số tập lệnh thiết lập ban đầu trong gói .deb?

Câu trả lời:


15

Với một debian/preinsttệp bạn có thể thực hiện các hành động khi cài đặt nhưng không nâng cấp.

#!/bin/sh
set -e

case "$1" in
    install)
        # do some magic
        ;;

    upgrade|abort-upgrade)
        ;;

    *)
        echo "postinst called with unknown argument \`$1'" >&2
        exit 0
        ;;
esac

#DEBHELPER#

exit 0

Mặc dù như tên của nó, điều này được chạy trước khi gói của bạn được cài đặt. Vì vậy, bạn có thể không thể làm những gì bạn cần ở đây. Hầu hết các gói chỉ kiểm tra trong giai đoạn cấu hình postinstnếu người dùng đã được tạo. Đây làcolord

$ cat  /var/lib/dpkg/info/colord.postinst
#!/bin/sh

set -e

case "$1" in
    configure)

# create colord group if it isn't already there
    if ! getent group colord >/dev/null; then
            addgroup --quiet --system colord
    fi

# create the scanner group if it isn't already there
    if ! getent group scanner >/dev/null; then
        addgroup --quiet --system scanner
    fi

# create colord user if it isn't already there
    if ! getent passwd colord >/dev/null; then
            adduser --system --ingroup colord --home /var/lib/colord colord \
        --gecos "colord colour management daemon"
        # Add colord user to scanner group
        adduser --quiet colord scanner
    fi

# ensure /var/lib/colord has appropriate permissions
    chown -R colord:colord /var/lib/colord

    ;;
esac    



exit 0

28

Kiểm tra sơ đồ này từ wiki Debian về cách các tập lệnh bảo trì được gọi: Lưu đồ kịch bản duy trì Debian

Nếu bạn đi xuống phía bên tay trái (mọi thứ đều đi theo đường dẫn ok), bạn sẽ thấy postinsttập lệnh được gọi với phiên bản được cấu hình gần đây nhất. Điều này cho bạn cơ hội để phân biệt giữa nâng cấp và cài đặt mới - trong trường hợp nâng cấp, postinst của bạn sẽ được gọi như

postinst configure 1.23-0ubuntu1

nơi 1.23-0ubuntu1là phiên bản cài đặt trước đó của gói của bạn, trong khi đối với một tươi cài đặt nó sẽ được gọi như

postinst configure

Điều này cũng cho phép bạn xử lý trường hợp khi bạn cần thực hiện một hành động khi nâng cấp từ một phiên bản cụ thể - bạn có thể kiểm tra postinstphiên bản đó.

Điều này giúp dễ dàng kiểm tra xem tập lệnh đang được thực hiện trên 'cài đặt' hay 'nâng cấp'. Nếu $ 2 là null, thì đó là cài đặt. vì thế:

if [ -z "$2" ]; then
  do install stuff
else
  do upgrade stuff
fi

Lưu ý rằng tham số bổ sung cũng được thông qua trong trường hợp bạn đã gỡ bỏ gói (nhưng không xóa nó) và cài đặt lại.
thắp sáng

3

Bạn có thể sử dụng tập lệnh debian / preinst kết hợp với postinst.

Trong tập lệnh trước, hãy kiểm tra tệp mà pkg của bạn chắc chắn sẽ cài đặt. Nếu có, không làm gì cả (vì gói của bạn đã được cài đặt trước đó), nếu không, hãy thực hiện các bước thiết lập của bạn.

Nếu các bước thiết lập của bạn yêu cầu pkg của bạn được cài đặt (trong trường hợp đó, phần trên sẽ không hoạt động vì preinst chạy trước khi cài đặt), thì tập lệnh preinst của bạn có thể viết một tệp, ví dụ: / tmp / setupmypkg. Tập lệnh postinst của bạn có thể chỉ cần kiểm tra xem tập tin đó có hiện diện hay không và nếu có thì hãy thực hiện hai điều sau:

  • các bước thiết lập ban đầu của bạn
  • xóa tập tin / tmp / setupmypkg

1
Vâng, điều này sẽ làm việc và tôi hiện đang làm một cái gì đó tương tự. Nhưng nó vẫn có vẻ hơi hack ... Tôi đã hy vọng có nhiều cách bản địa hơn để làm điều đó. Nó không giống như một yêu cầu kỳ lạ phải không?
Jeroen

1

Tôi thấy rằng việc kiểm tra $ 2 trong tập lệnh "cấu hình postinst" của bạn không hoạt động đúng nếu bạn đã cài đặt gói của mình một lần trước đó, sau đó gỡ cài đặt nó (nhưng không xóa), sau đó thử cài đặt lại. Trong trường hợp này, tập lệnh postinst vẫn nhận được một đối số phiên bản cho bước "cấu hình postinst".

Tuy nhiên, nếu bạn đã cài đặt gói trước đó, sau đó xóa VÀ lọc nó, sau đó cài đặt lại, tập lệnh "postinst configure" sẽ KHÔNG nhận được một đối số phiên bản trong $ 2


0

Tôi không nghĩ vậy nhưng bạn có thể dễ dàng sửa đổi các tập lệnh preinst / postinst để kiểm tra xem gói có được cài đặt lần đầu tiên không và thực hiện hành động chuẩn.

Có thể là một cái gì đó như thế này,

ở trước

if not is_package_istalled():
    export MY_PACKAGE_FIRST_INSTALL

trong postinst,

if MY_PACKAGE_FIRST_INSTALL:
    Do First Install Setup 

Biên tập

Hmm, có thể bạn chỉ có thể kiểm tra tất cả điều này trực tiếp trong postinst vì tôi nghĩ dpkg sẽ không đặt trạng thái của gói như đã cài đặt trước khi thực hiện postinst nhưng tôi không chắc. Vì vậy, những điều trên có thể đến,

trong postinst,

if not is_package_istalled():
    Do First Install Setup 

Trong đó, is_package_installed có thể là chức năng của bạn để phát hiện trạng thái cài đặt. Có thể là một cái gì đó như 'dpkg --status packagename'

HOẶC LÀ

Tại sao không chỉ đơn giản là kiểm tra xem những thay đổi bạn muốn thực hiện đã ở đó chưa và chỉ tiến hành nếu không.


Tôi không hiểu IS_INSTALLED đến từ đâu?
Jeroen

Không có IS_INSTALLED, nó chỉ là mã giả. Chỉ là một ví dụ. IS_INSTALLED có thể là đầu ra của một lệnh như 'dpkg --status pack_name' Ý tôi là bạn có thể kiểm tra xem gói có được cài đặt trước hay không, đặt var trạng thái và sau đó dựa trên trạng thái var này hành động trong postinst.
Owais Lone
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.