Làm thế nào tôi có thể cài đặt các gói mà không bắt đầu các dịch vụ liên quan của họ?


13

Như bạn có thể biết, theo mặc định khi bạn cài đặt gói trên hệ thống dựa trên Debian hoặc Ubuntu, nếu gói chứa dịch vụ, dịch vụ đó thường sẽ được bật và bắt đầu tự động khi bạn cài đặt gói.

Đây là một vấn đề đối với tôi.

Tôi thấy mình cần quản lý các mẫu để xây dựng các container LXC. Có một số container, mỗi container tương ứng với bản phát hành Debian hoặc Ubuntu. (Ngoài ra còn có các container dựa trên Red Hat, nhưng chúng không liên quan ở đây.)

/var/lib/libvirt/filesystems/debian6_template
/var/lib/libvirt/filesystems/debian7_template
/var/lib/libvirt/filesystems/ubuntu1004_template
/var/lib/libvirt/filesystems/ubuntu1204_template

Thỉnh thoảng tôi sẽ thấy rằng các mẫu có một gói bị thiếu hoặc cần một số thay đổi khác, vì vậy tôi sẽ chroot vào chúng để cài đặt gói. Thật không may khi tôi làm điều đó, tôi kết thúc với một vài bản sao của dịch vụ của gói đang chạy!

Ví dụ, tôi thấy các mẫu không có trình nền syslog, vì vậy tôi đã cài đặt một mẫu:

for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done

Và kịp thời xử lý với bốn bản sao của rsyslog đang chạy. Chưa kể hai bản exim4. Giáo sư!


Tôi đã đọc ở đâu đó (mặc dù bây giờ tôi không thể tìm thấy nó nữa) rằng nó không được phép bắt đầu dịch vụ khi chạy trong một chroot, nhưng điều đó rõ ràng không xảy ra ở đây.

Một cuộc gọi hack khó chịu tiềm tàng có thể thay thế tạm thời các lệnh khác nhau thực sự bắt đầu các dịch vụ, chẳng hạn như start-stop-daemon, và initctlmặc dù đây là công việc nhiều hơn tôi thực sự muốn làm. Nếu tôi không có lựa chọn nào khác, mặc dù ...

Giải pháp lý tưởng ở đây sẽ là cho các hệ thống dựa trên Debian ngừng thực hiện công việc tào lao này, nhưng không thành công, có lẽ là một tùy chọn dòng lệnh tối nghĩa hoặc không có giấy tờ cho apt-get?

Trong trường hợp không rõ ràng, tôi thực sự muốn giữ bất cứ điều gì liên quan đến việc quản lý các mẫu bên ngoài các mẫu, nếu có thể.

Câu trả lời:


23

Đối với debian, bạn có thể làm điều này với chính sách-rc.d . Đây là một lời giải thích :

Các tập lệnh bảo trì của gói được cho là chỉ giao tiếp với hệ thống init bằng cách gọi invoke-rc.d, update-rc.d và các tiêu đề của tập lệnh init LSB ... trước khi thực hiện hành động của nó, hãy kiểm tra xem /usr/sbin/policy-rc.d có thể thực thi được, sẽ gọi nó với tên dịch vụ tương ứng và số runlevel hiện tại trên dòng lệnh của nó và hành động theo mã thoát của nó. Ví dụ: giá trị trả về 101 sẽ ngăn hành động được lên kế hoạch thực hiện. Điều này bao gồm tự động bắt đầu dịch vụ khi cài đặt gói cũng như dừng dịch vụ khi gỡ gói và giảm nghi thức dừng nâng cấp-khởi động lại trong quá trình nâng cấp gói để chỉ thực hiện nâng cấp có thể khiến phiên bản cũ của dịch vụ chạy

Vì bạn không muốn bất kỳ dịch vụ nào bắt đầu, tập lệnh chính sách-RC.d của bạn có thể chỉ đơn giản là

#!/bin/sh
exit 101

Đây là kỹ thuật được sử dụng bởi các công cụ như pbuilder và Docker mkimage-debootstrap .

Thật không may, kỹ thuật này không hoạt động với chroots Ubuntu . Các gói tích hợp với lệnh khởi động hệ thống khởi động / usr / sbin / initctl thay vì invoke-rc.d trong khi cài đặt và initctl không tham khảo chính sách-rc.d. Theo tác giả mới nổi, cách giải quyết là thay thế / sbin / initctl bằng một liên kết tượng trưng đến / bin / true trong một chroot. Bạn cũng có thể thấy điều này trong mkimage-debootstrap, họ làm

dpkg-divert --local --rename --add /sbin/initctl
ln -sf /bin/true sbin/initctl

Điều này có vẻ khá sạch sẽ, mặc dù nó cũng sẽ phải được gỡ bỏ trước khi tạo một thùng chứa từ mẫu.
Michael Hampton

1
Cảm ơn vì điều đó. Cuối cùng tôi có thể phải xé toạc kịch bản mkimage-debootstrap của Docker, vì dường như họ đã giải quyết được vấn đề này.
Michael Hampton

4

Bạn có thể làm:

export RUNLEVEL=1
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
    chroot $template apt-get install rsyslog
done
exit

Tôi đã không thử nó với chroot, nhưng nó sẽ hoạt động. Đầu tiên, nó đặt biến môi trường RUNLEVEL, vì vậy các quy trình được khởi tạo bởi apt-get sẽ không khởi động bất kỳ dịch vụ nào, vì chúng sẽ "nghĩ" hệ thống đang chạy trong chế độ đơn. Khi môi trường được sửa đổi theo cách nó có thể ảnh hưởng đến các lệnh trong tương lai, cần phải thoát shell khi môi trường đã sửa đổi không còn cần thiết, điều này được thực hiện bằng lệnh exit ở cuối. Có thể có một số gói (hiếm?) Sẽ không cài đặt đúng ở chế độ đơn (nhưng AFAIK điều này không phải là vấn đề trong hầu hết các trường hợp).


export RUNLEVEL=1phần quan trọng ở đây? Chính xác thì nó gây ra chuyện gì?
Michael Hampton

@MichaelHampton Tôi tin rằng biến môi trường RUNLEVEL sẽ cung cấp mức chạy hiện tại. Trong trường hợp này, anh ta chỉ ghi đè lên nó để bất kỳ ứng dụng nào cũng nghĩ rằng nó đang chạy trên 1. Đó là loại "bùn" nhưng nên đủ.
WinkyWolly

Thêm lời giải thích cho câu trả lời ban đầu. Về cơ bản đây là những gì @WinkyWolly nói.
DavisNT

Thật không may, rsyslogtình cờ là một trong những gói "hiếm" đã nổ tung hoàn toàn khi cố gắng cài đặt theo cách này. Tuy nhiên, điều này có thể vẫn hữu ích, vì vậy bạn có thể giữ upvote :)
Michael Hampton
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.