SNAP-PAC(8) snap-pac SNAP-PAC(8)

snap-pac - قلاب‌های pacman که از snapper برای ایجاد اسنپ‌شات‌های btrfs پیش/پس از تراکنش مانند YaST در openSUSE استفاده می‌کنند

این مجموعه‌ای از قلاب‌ها (hooks) و اسکریپت‌های pacman است که باعث می‌شود snapper به‌طور خودکار پیش و پس از هر تراکنش pacman یک اسنپ‌شات (تصویر لحظه‌ای) تهیه کند، شبیه به کاری که YaST در OpenSuse انجام می‌دهد. این قابلیت روش ساده‌ای را برای بازگردانی تغییرات سیستم پس از یک تراکنش pacman فراهم می‌آورد.

از آنجا که این‌ها قلاب‌های pacman هستند، تفاوتی نمی‌کند که چگونه pacman را فراخوانی کنید—خواه به‌طور مستقیم، از طریق یک دستیار AUR یا با استفاده از یک نام مستعار (alias)—هر زمان که pacman بسته‌ای را نصب، ارتقا یا حذف کند، snapper اسنپ‌شات‌ها را ایجاد خواهد کرد. دستور pacman استفاده‌شده در بخش توضیحات snapper برای اسنپ‌شات‌ها ثبت می‌شود. علاوه بر این، در حین تراکنش pacman، شماره‌های اسنپ‌شات برای هر پیکربندی snapper بر روی صفحه نمایش و در گزارش (log) pacman خروجی داده می‌شوند تا کاربر بتواند به‌راحتی تغییراتی را که مایل به بازگردانی آن‌هاست، پیدا کند.

هنگامی که pacman را اجرا می‌کنید، اسنپ‌شات‌های پیش/پس snapper به‌طور خودکار ایجاد می‌شوند. برای مشاهده یک نمونه کامل‌تر، بخش مثال (EXAMPLE) را ببینید.

$ sudo pacman -S vim
resolving dependencies...
looking for conflicting packages...
Packages (1) vim-8.2.2489-1
Total Installed Size:  3.79 MiB
Net Upgrade Size:      0.00 MiB
:: Proceed with installation? [Y/n]
(1/1) checking keys in keyring                     [############] 100%
(1/1) checking package integrity                   [############] 100%
(1/1) loading package files                        [############] 100%
(1/1) checking for file conflicts                  [############] 100%
(1/1) checking available disk space                [############] 100%
:: Running pre-transaction hooks...
(1/1) Performing snapper pre snapshots for the following configurations...
==> root: 7394
:: Processing package changes...
(1/1) installing vim                               [############] 100%
:: Running post-transaction hooks...
(1/4) Arming ConditionNeedsUpdate...
(2/4) Updating icon theme caches...
(3/4) Updating the desktop file MIME type cache...
(4/4) Performing snapper post snapshots for the following configurations...
==> root: 7395

برای لغو تغییرات ناشی از یک تراکنش pacman، از snapper undochange استفاده کنید. برای جزئیات بیشتر و همچنین مشاهده مثال‌ها، به snapper(8) مراجعه کنید.

اگر سیستم با خرابی شدیدی مواجه شد—مثلاً snapper به دلیلی از دست رفته باشد و نتوانید آن را بازگردانید—باید به روش‌های پیشرفته‌تری متوسل شوید؛ مانند تهیه یک اسنپ‌شات از اسنپ‌شات pre و تبدیل آن به زیرحجم (subvolume) پیش‌فرض یا سوار کردن (mount) آن به عنوان /. به احتمال زیاد برای انجام هر یک از این کارها به یک فلش‌مموری زنده (Live USB) نیاز خواهید داشت تا وارد یک محیط chroot شوید. ابزار Snapper دارای قابلیت snapper rollback است، اما پیکربندی سیستم شما باید به‌درستی برای استفاده از آن تنظیم شده باشد. روند دقیق کار به نوع پیکربندی خاص سیستم شما بستگی دارد. احتیاط کنید.

توجه داشته باشید که قلاب‌های پیش از تراکنش، قبل از انجام تراکنش pacman اما (در صورت وجود) پس از همگام‌سازی پایگاه‌داده pacman اجرا می‌شوند. به عبارت دیگر، اگر دستور pacman -Syu را اجرا کنید و طبق دستورالعمل‌های بالا ارتقا را به عقب برگردانید (roll back کنید)، پایگاه‌داده pacman به وضعیت قبلی بازنخواهد گشت. در نتیجه، اگر پس از ارتقا و بازگردانی آن، بسته‌ای را نصب کنید، احتمالاً با یک ارتقای جزئی (partial upgrade) مواجه خواهید شد که پشتیبانی نمی‌شود.

بسته snap-pac را با استفاده از pacman نصب کنید:

pacman -S snap-pac

همچنین می‌توانید آخرین نسخه منتشرشده و امضای آن را دریافت کنید. سپس فایل دانلودشده را اعتبارسنجی نمایید:

gpg --verify snap-pac-<version>.tar.gz.sig

که در آن <version> شماره نسخه‌ای است که دریافت کرده‌اید.

در نهایت، اجرا کنید:

make install

من فایل فشرده (tarball) نسخه منتشرشده و کامیت‌ها را با کلید PGP خود امضا کرده‌ام. با شروع از نسخه 2.2، فایل‌های tarball با کلید من با اثر انگشت (fingerprint) زیر امضا می‌شوند: F7B28C61944FE30DABEEB0B01070BCC98C18BD66.

برای نسخه‌های قبلی، اثر انگشت کلید برابر بود با: 8535CEF3F3C38EE69555BF67E4B5E45AA3B8C5C3.

ابزارهای python، pacman و snapper همگی مورد نیاز هستند.

برای اجرای آزمون‌ها، ابزار pytest مورد نیاز است. برای اجرای آزمایش‌ها این دستور را اجرا کنید:

make test

معمولاً نیازی نیست که خودتان مستندات را بسازید و به‌سادگی می‌توانید با مراجعه به مستندات برخط (آنلاین) یا با دسترسی به صفحه راهنما (man page) آن را مشاهده کنید:

man 8 snap-pac

برای ساخت مستندات، به sphinx نیاز است. برای ساخت مستندات می‌توانید دستور زیر را اجرا کنید:

make docs

مستندات html حاصل در مسیر docs/build/index.html قرار خواهد گرفت. علاوه بر این، این دستور صفحه راهنما را نیز تولید می‌کند که در مسیر man8 قرار می‌گیرد.

پیکربندی از طریق فایل‌های پیکربندی ini پایتون انجام می‌شود. تنظیمات پیش‌فرض باید برای بیشتر کاربران مناسب باشد، بنابراین ممکن است اصلاً نیازی به انجام پیکربندی نداشته باشید. به‌طور پیش‌فرض تنها از پیکربندی root در snapper اسنپ‌شات گرفته می‌شود.

یک فایل نمونه پیکربندی همراه با توضیحات در مسیر /etc/snap-pac.ini قرار دارد.

آن را با ویرایشگر دلخواه خود ویرایش کنید. این فایل دارای کامنت‌های توضیحی است و باید به‌اندازه کافی واضح و خودتوضیح باشد.

هر بخش (section) با یکی از پیکربندی‌های snapper مطابقت دارد. برای افزودن پیکربندی‌های دیگر snapper جهت اسنپ‌شات‌گیری، بخش‌های جدیدی اضافه کنید. به‌طور پیش‌فرض تنها از پیکربندی root اسنپ‌شات گرفته می‌شود. علاوه بر این، می‌توانید بخشی به نام DEFAULT اضافه کنید که گزینه‌های آن برای تمامی پیکربندی‌های snapper اعمال می‌شوند، مگر اینکه در بخش‌های بعدی بازنویسی (override) شوند.

هر بخش می‌تواند شامل ورودی‌های زیر باشد:

  • desc_limit - عدد صحیح؛ حداکثر طول رشته توضیحات پیش از کوتاه‌سازی (truncate). پیش‌فرض: 72
  • important_packages - فهرستی از رشته‌ها؛ نام بسته‌هایی که اگر در تراکنش pacman دخیل باشند، مقدار important=yes را به userdata در snapper برای آن جفت اسنپ‌شات اضافه می‌کند. پیش‌فرض: []
  • important_commands - فهرستی از رشته‌ها؛ دستورات والدی که مقدار important=yes را به userdata در snapper برای آن جفت اسنپ‌شات اضافه می‌کنند. پیش‌فرض: []
  • pre_description - رشته؛ توضیح برای اسنپ‌شات پیشین (pre). پیش‌فرض: دستور والدی که قلاب pacman را فراخوانی کرده است.
  • post_description - رشته؛ توضیح برای اسنپ‌شات پسین (post). پیش‌فرض: فهرستی از بسته‌های نصب، ارتقا یا حذف‌شده که با فاصله از هم جدا شده‌اند.
  • snapshot - بولی (boolean)؛ مشخص می‌کند که آیا از این پیکربندی اسنپ‌شات گرفته شود یا خیر. پیش‌فرض: برای پیکربندی root مقدار True و در غیر این صورت False.
  • userdata - فهرستی از رشته‌ها؛ جفت‌های کلید-مقدار که برای آن جفت اسنپ‌شات به userdata اضافه می‌شوند. پیش‌فرض: []

غیرفعال کردن اسنپ‌شات‌ها برای پیکربندی root و فعال کردن آن‌ها برای پیکربندی home:

[root]
snapshot = False
[home]
snapshot = True

تنظیم snapper برای افزودن مقدار userdata با important=yes برای هر اسنپ‌شات در پیکربندی root هنگامی که یک ارتقای سیستمی انجام می‌شود:

[root]
important_commands = ["pacman -Syu"]

تنظیم snapper برای افزودن مقدار userdata با important=yes برای هر اسنپ‌شات در پیکربندی root هنگامی که یک تراکنش pacman با بسته‌های linux و linux-lts سر و کار دارد:

[root]
important_packages = ["linux", "linux-lts"]

در اینجا یک مثال کامل‌تر با چندین گزینه تنظیم‌شده برای پیکربندی‌های مختلف آمده است. در این حالت، هنگامی که بسته‌های linux و linux-lts بخشی از تراکنش باشند، اسنپ‌شات پیکربندی root دارای مقدار important=yes خواهد بود. علاوه بر این، در زمان ارتقای کامل سیستم نیز اسنپ‌شات‌های root با important=yes علامت‌گذاری می‌شوند. توجه داشته باشید که نیازی به افزودن snapshot = True برای پیکربندی root نیست زیرا این مقدار پیش‌فرض است.

این فایل همچنین اسنپ‌شات‌ها را برای پیکربندی snapper مربوط به home فعال می‌کند و userdata با مقدار requestid=42,user=arthur را به تمامی اسنپ‌شات‌های آن پیکربندی می‌افزاید. علاوه بر این، توضیحات اسنپ‌شات پسین (post) بازنویسی شده است.

[root]
important_packages = ["linux", "linux-lts"]
important_commands = ["pacman -Syu"]
[home]
snapshot = True
userdata = ["requestid=42", "user=arthur"]
post_description = "pacman transaction post snapshot"

برای جلوگیری موقت از ایجاد اسنپ‌شات برای یک دستور خاص pacman، متغیر محیطی SNAP_PAC_SKIP را تنظیم کنید. به عنوان مثال:

sudo SNAP_PAC_SKIP=y pacman -Syu

در اینجا مثالی از نحوه ایجاد اسنپ‌شات‌ها و چگونگی بازگردانی یک تراکنش pacman آورده شده است. در اینجا بسته nano نصب می‌شود:

pacman -S nano
resolving dependencies...
looking for conflicting packages...
Packages (1) nano-2.5.3-1
Total Installed Size:  2.14 MiB
:: Proceed with installation? [Y/n] Y
(1/1) checking keys in keyring                               [######################################] 100%
(1/1) checking package integrity                             [######################################] 100%
(1/1) loading package files                                  [######################################] 100%
(1/1) checking for file conflicts                            [######################################] 100%
(1/1) checking available disk space                          [######################################] 100%
:: Running pre-transaction hooks...
(1/1) Performing snapper pre snapshots for the following configurations...
=> root: 1033
:: Processing package changes...
(1/1) installing nano                                        [######################################] 100%
:: Running post-transaction hooks...
(1/1) Performing snapper post snapshots for the following configurations...
=> root: 1034

شماره اسنپ‌شات snapper برای هر پیکربندی مورد استفاده نمایش داده می‌شود. این مورد در گزارش (log) pacman نیز ثبت می‌گردد.

اسنپ‌شات‌های ایجادشده قبل و بعد از تراکنش pacman در اینجا آورده شده است:

snapper -c root list -t pre-post | tail -n 1
1033  | 1034   | Fri 22 Apr 2016 01:54:13 PM CDT | Fri 22 Apr 2016 01:54:14 PM CDT | pacman -S nano      |

آنچه در طول تراکنش تغییر کرده است:

snapper -c root status 1033..1034
+..... /etc/nanorc
c..... /etc/snapper/.snap-pac-pre
+..... /usr/bin/nano
+..... /usr/bin/rnano
+..... /usr/share/doc/nano
+..... /usr/share/doc/nano/faq.html
+..... /usr/share/doc/nano/fr
+..... /usr/share/doc/nano/fr/nano.1.html
+..... /usr/share/doc/nano/fr/nanorc.5.html
+..... /usr/share/doc/nano/fr/rnano.1.html

خروجی بالا کوتاه شده است، اما ادامه دارد. برای آشنایی با معنای هر نماد، به snapper(8) مراجعه کنید. همچنین می‌توانید دستور snapper diff را به همین شیوه اجرا کنید.

سپس، برای بازگردانی تراکنش pacman:

snapper -c root undochange 1033..1034
create:0 modify:3 delete:100

اکنون nano به همراه تمام فایل‌هایی که تغییر داده بود دیگر نصب نیست:

pacman -Qi nano
error: package 'nano' was not found

برنامه snap-pac تنها از پیکربندی root اسنپ‌شات می‌گیرد.

این رفتار پیش‌فرض است. بخش پیکربندی (CONFIGURATION) را ببینید.

هنگام اجرای pacman هیچ اسنپ‌شاتی گرفته نمی‌شود.

هیچ پیکربندی snapper برای قلاب‌های pacman مربوط به snap-pac تنظیم نشده است. به‌طور پیش‌فرض، snap-pac برای پیکربندی root و هر پیکربندی دیگری که گزینه SNAPSHOT در فایل پیکربندی آن روی yes تنظیم شده باشد، اسنپ‌شات می‌گیرد. بخش پیکربندی (CONFIGURATION) را ببینید.

پس از بازیابی اسنپ‌شات از snap-pac، پایگاه‌داده pacman قفل است.

اسنپ‌شات‌های پیشین/پسین زمانی گرفته می‌شوند که pacman در حال اجرا است، بنابراین این امر مورد انتظار است. دستورالعمل‌هایی را که pacman به شما ارائه می‌دهد دنبال کنید (برای مثال، حذف فایل قفل). می‌توانید فایل قفل پایگاه‌داده را به یک فیلتر snapper اضافه کنید تا snapper هنگام اجرای دستوراتی چون snapper diff، snapper status، snapper undochange و غیره آن را در نظر نگیرد. برای اطلاعات بیشتر، بخش فیلترها (Filters) را در snapper(8) ببینید.

آیا snap-pac از پارتیشن‌های /boot غیر btrfs نسخه پشتیبان تهیه می‌کند؟

خیر، اما می‌توانید قلابی اضافه کنید که این کار را برای شما انجام دهد. شبیه به نمونه زیر خواهد بود:

[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Package
Target = linux
[Action]
Description = Backing up /boot...
When = PreTransaction
Exec = /usr/bin/rsync -avzq --delete /boot /.bootbackup

توجه داشته باشید که احتمالاً می‌خواهید نام فایل را با یک پیشوند عددی کمتر از 05 نام‌گذاری کنید تا قبل از گرفته شدن اسنپ‌شات pre توسط snap-pac اجرا شود. این کار تضمین می‌کند اسنپ‌شاتی که گرفته می‌شود، شامل نسخه پشتیبان پارتیشن بوت مطابق با وضعیت سیستم باشد. به عنوان مثال، می‌توانید نام آن را 04-backupboot.hook بگذارید.

چگونه ماژول‌های قدیمی هسته را هنگام ارتقای هسته به‌طور خودکار پیوند (link) دهم؟

این رفتار دیگر بخشی از این بسته نیست. از یک قلاب pacman مانند نمونه زیر استفاده کنید:

[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Package
Target = linux
[Action]
Description = Symlinking old kernel modules...
When = PostTransaction
Exec = /usr/bin/bash -c "find /usr/lib/modules -xtype l -delete; ln -sv /.snapshots/$(snapper -c root list | awk 'END{print $1}')/snapshot/usr/lib/modules/$(uname -r) /usr/lib/modules/"

Wes Barnett

2024, Wes Barnett, PhD

July 1, 2024