From 7b8404fdee4b897cd8f19207cef6476041c5b7de Mon Sep 17 00:00:00 2001 From: Wes Barnett Date: Thu, 11 Mar 2021 19:51:08 -0500 Subject: [PATCH] Set up pages --- LICENSE | 339 --------------------------------- README.md | 50 ----- extra/snap-pac.ini | 24 --- hooks/00_snapper-pre.hook | 32 ---- hooks/10_snap-pac-removal.hook | 28 --- hooks/zy_snapper-post.hook | 31 --- hooks/zz_snap-pac-install.hook | 28 --- man8/snap-pac.8 | 202 -------------------- scripts/snap_pac.py | 145 -------------- tests/test_script.py | 106 ----------- 10 files changed, 985 deletions(-) delete mode 100644 LICENSE delete mode 100644 README.md delete mode 100644 extra/snap-pac.ini delete mode 100644 hooks/00_snapper-pre.hook delete mode 100644 hooks/10_snap-pac-removal.hook delete mode 100644 hooks/zy_snapper-post.hook delete mode 100644 hooks/zz_snap-pac-install.hook delete mode 100644 man8/snap-pac.8 delete mode 100755 scripts/snap_pac.py delete mode 100644 tests/test_script.py diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 23cb790..0000000 --- a/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - {description} - Copyright (C) {year} {fullname} - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - {signature of Ty Coon}, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/README.md b/README.md deleted file mode 100644 index 69a281d..0000000 --- a/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# snap-pac - -![Tests](https://github.com/wesbarnett/snap-pac/workflows/Tests/badge.svg) - -## Synopsis - -This is a set of pacman hooks and script that automatically causes snapper to -perform a pre and post snapshot before and after pacman transactions, similar to -how YaST does with OpenSuse. This provides a simple way to undo changes to a -system after a pacman transaction. - -## Installation - -Install the `snap-pac` package using pacman. - -Alternatively [download the latest release] and signature , verify the download, and -then run `make install`. - -I have signed the release tarball and commits with my PGP key. Starting with release -2.2, the tarballs are signed with my key with fingerprint -`F7B28C61944FE30DABEEB0B01070BCC98C18BD66`. - -For previous releases, the key's fingerprint was -`8535CEF3F3C38EE69555BF67E4B5E45AA3B8C5C3`. - -## Configuration - -Most likely, configuration is not needed. By default, the snapper configuration named -`root` will have pre/post snapshots taken for every pacman transaction. - -To configure, copy the example configuration file: - -```bash -cp /etc/snap-pac.ini{.example,} -``` - -Then edit with your favorite editor. The file is commented and should be -self-explanatory. - -## Documentation - -Run `man 8 snap-pac` after installation. - -## Troubleshooting - -After reviewing the man page, [check the issues page] and file a new issue if your -problem is not covered. - -[download the latest release]: https://github.com/wesbarnett/snap-pac/releases -[check the issues page]: https://github.com/wesbarnett/snap-pac/issues diff --git a/extra/snap-pac.ini b/extra/snap-pac.ini deleted file mode 100644 index 7e32a4b..0000000 --- a/extra/snap-pac.ini +++ /dev/null @@ -1,24 +0,0 @@ -# snap-pac example configuration file - -# Each section corresponds with a snapper configuration. Add additional sections to add -# other configurations to be snapshotted. By default, only the root configuration is snapshotted. - -[root] -# How many characters to limit the description for snapper. -desc_limit = 72 - -# Whether or not to take snapshots of this snapper configuration -snapshot = True - -# What snapper cleanup algorithm to use -cleanup_algorithm = number - -# Pre snapshot description. Default is the pacman command that triggered the hook -#pre_description = pacman pre snapshot - -# Post snapshot description. Default is the list of packages involved in the pacman transaction -#post_description = pacman post snapshot - -# Example for another snapper configuration named "home" -# [home] -# snapshot = True diff --git a/hooks/00_snapper-pre.hook b/hooks/00_snapper-pre.hook deleted file mode 100644 index 79af5f6..0000000 --- a/hooks/00_snapper-pre.hook +++ /dev/null @@ -1,32 +0,0 @@ -# snap-pac -# https://github.com/wesbarnett/snap-pac -# Copyright (C) 2016, 2017, 2018 James W. Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -[Trigger] -Operation = Upgrade -Operation = Install -Operation = Remove -Type = Package -Target = * - -[Action] -Description = Performing snapper pre snapshots for the following configurations... -Depends = snap-pac -When = PreTransaction -Exec = /usr/share/libalpm/scripts/snap-pac pre -NeedsTargets -AbortOnFail diff --git a/hooks/10_snap-pac-removal.hook b/hooks/10_snap-pac-removal.hook deleted file mode 100644 index 6c8f921..0000000 --- a/hooks/10_snap-pac-removal.hook +++ /dev/null @@ -1,28 +0,0 @@ -# snap-pac -# https://github.com/wesbarnett/snap-pac -# Copyright (C) 2016, 2017, 2018 James W. Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -[Trigger] -Operation = Remove -Type = Package -Target = snap-pac - -[Action] -Description = You are removing snap-pac. No post transaction snapshots will be taken. -Depends = snap-pac -When = PreTransaction -Exec = /usr/bin/bash -c "rm -f /tmp/snap-pac-pre_*" diff --git a/hooks/zy_snapper-post.hook b/hooks/zy_snapper-post.hook deleted file mode 100644 index 2513dc6..0000000 --- a/hooks/zy_snapper-post.hook +++ /dev/null @@ -1,31 +0,0 @@ -# snap-pac -# https://github.com/wesbarnett/snap-pac -# Copyright (C) 2016, 2017, 2018 James W. Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -[Trigger] -Operation = Upgrade -Operation = Install -Operation = Remove -Type = Package -Target = * - -[Action] -Description = Performing snapper post snapshots for the following configurations... -Depends = snap-pac -When = PostTransaction -Exec = /usr/share/libalpm/scripts/snap-pac post -NeedsTargets diff --git a/hooks/zz_snap-pac-install.hook b/hooks/zz_snap-pac-install.hook deleted file mode 100644 index 4beeb68..0000000 --- a/hooks/zz_snap-pac-install.hook +++ /dev/null @@ -1,28 +0,0 @@ -# snap-pac -# https://github.com/wesbarnett/snap-pac -# Copyright (C) 2016, 2017, 2018 James W. Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -[Trigger] -Operation = Install -Type = Package -Target = snap-pac - -[Action] -Description = You are installing snap-pac, so no post transaction snapshots will be taken. -Depends = snap-pac -When = PostTransaction -Exec = /usr/bin/true diff --git a/man8/snap-pac.8 b/man8/snap-pac.8 deleted file mode 100644 index 985fce1..0000000 --- a/man8/snap-pac.8 +++ /dev/null @@ -1,202 +0,0 @@ -'\" t -.TH SNAP-PAC 8 2021-01-29 SNAP-PAC -.SH NAME -snap-pac \- Pacman hooks that use snapper to create pre/post btrfs snapshots -like openSUSE's YaST - -.SH DESCRIPTION - -This is a set of \fIpacman\fR hooks and script that causes \fIsnapper\fR to -automatically take a pre and post snapshot before and after pacman transactions, -similar to how YaST does with OpenSuse. This provides a simple way to undo -changes to a system after a pacman transaction. - -Because these are pacman hooks, it doesn't matter how you call pacman—whether -directly, through an AUR helper, or using an alias—snapper will create the -snapshots when pacman installs, upgrades, or removes a package. The pacman -command used is logged in the snapper description for the snapshots. -Additionally the snapshot numbers are output to the screen and to the pacman log -for each snapper configuration during the pacman transaction, so that the user can -easily find which changes he or she may want to revert. - -To undo changes from a pacman transaction, use \fIsnapper undochange\fR. See -\fBsnapper\fR(8) and \fBEXAMPLES\fR. - -If you have severe breakage—like snapper is gone for some reason and you can't -get it back—you'll have to resort to more extreme methods, such as taking a -snapshot of the pre snapshot and making it the default subvolume or mounting it -as \fI/\fR. Most likely you'll need to use a live USB to get into a chroot -environment to do any of these things. Snapper has a snapper rollback feature, -but your setup has to be properly configured to use it. The exact procedure -depends on your specific setup. Be careful. - -.SH CONFIGURATION -Configuration is done via Python ini configuration files. The defaults of the -should be suitable for most users, so you may not need to do any configuration at all. -By default only the "root" snapper configuration is snapshotted. - -A commented example configuration files is located at \fI/etc/snap-pac.ini.example\fR. - -.SH ENVIRONMENT VARIABLES - -To temporarily prevent snapshots from being performed for a single -pacman command, set the environment variable \fISNAP_PAC_SKIP\fR. For -example: - -.EX - - $ sudo SNAP_PAC_SKIP=y pacman -Syu - -.EE - - -.SH EXAMPLES - -Here is an example of how the snapshots are created and how to rollback and pacman -transaction. Here the \fBnano\fR package is installed: - -.EX - - # 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 - -.EE - -The snapper snapshot number is given for each snapper configuration that is -used. This is also logged in pacman's log. - -Here are the snapshots created before and after the pacman transaction: - -.EX - - # 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 | - -.EE - -Here is what changed during the transaction: - -.EX - - # 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 - -.EE - -The above output is truncated, but it continues. See the \fBsnapper\fR(8) to -for what each symbol means. You can also do \fBsnapper diff\fR in the same way. - -Then, to undo the \fBpacman\fR transaction: - -.EX - - # snapper -c root undochange 1033..1034 - create:0 modify:3 delete:100 - -.EE - -Now nano is no longer installed, along with all the files it changed: - -.EX - - $ pacman -Qi nano - error: package 'nano' was not found - -.EE - -.SH TROUBLESHOOTING - -.SS snap-pac is only taking snapshots of the root configuration. -That's the default behavior. See \fBCONFIGURATION\fR. - -.SS No snapshots are being taken when I run pacman. -No snapper configurations are set up for snap-pac's pacman hooks. By default -snap-pac will take snapshots for the root configuration and any other -configuration which has SNAPSHOT set to yes in its configuration file. -See \fBCONFIGURATION\fR. - -.SS After restoring snapshot from snap-pac, the pacman database is locked. -The pre/post snaphots are taken while pacman is running, so this is expected. -Follow the instructions pacman gives you (e.g., removing the lock file). You can add the -database lock file to a snapper filter so that snapper won't consider it when performing -\fBsnapper diff\fR, \fBsnapper status\fR, \fBsnapper undochange\fR, etc. See the -\fBFilters\fR section in \fBsnapper\fR(8) for more information. - - -.SH FAQ -.SS Does snap-pac backup non-btrfs /boot partitions? -No, but you can add a hook that does it for you. It would be -something like the following: - -.EX - - [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 - -.EE - -.SS How do I link old kernel modules automatically when the kernel is upgraded? -This behavior is no longer a part of this package. Use a pacman hook like the following: - - [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/" - -.SH HOMEPAGE -https://github.com/wesbarnett/snap-pac - -.SH AUTHORS -Wes Barnett - -.SH SEE ALSO -.BR alpm-hooks (5), -.BR snapper (8), -.BR snapper-configs (5), -.BR pacman (8) - diff --git a/scripts/snap_pac.py b/scripts/snap_pac.py deleted file mode 100755 index 6b86dbd..0000000 --- a/scripts/snap_pac.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/env python -# Copyright (C) 2021 Wes Barnett - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -"""Script for taking pre/post snapshots; run from pacman hooks.""" - -from argparse import ArgumentParser -from configparser import ConfigParser -import logging -from pathlib import Path -import os -import sys -import tempfile - - -logging.basicConfig(format="%(message)s", level=logging.INFO) - - -class SnapperCmd: - - def __init__(self, config, snapshot_type, cleanup_algorithm, description="", nodbus=False, pre_number=None): - self.cmd = ["snapper"] - if nodbus: - self.cmd.append("--no-dbus") - self.cmd.append(f"--config {config} create") - self.cmd.append(f"--type {snapshot_type}") - self.cmd.append(f"--cleanup-algorithm {cleanup_algorithm}") - self.cmd.append("--print-number") - if description: - self.cmd.append(f"--description \"{description}\"") - if snapshot_type == "post": - if pre_number is not None: - self.cmd.append(f"--pre-number {pre_number}") - else: - raise ValueError("snapshot type specified as 'post' but no pre snapshot number passed.") - - def __call__(self): - return os.popen(self.__str__()).read().rstrip("\n") - - def __str__(self): - return " ".join(self.cmd) - - -def get_snapper_configs(conf_file): - """Get the snapper configurations.""" - for line in conf_file.read_text().split("\n"): - if line.startswith("SNAPPER_CONFIGS"): - line = line.rstrip("\n").rstrip("\"").split("=") - return line[1].lstrip("\"").split() - - -def setup_config_parser(ini_file, parent_cmd, packages): - """Set up defaults for snap-pac configuration.""" - - config = ConfigParser() - config["DEFAULT"] = { - "snapshot": False, - "cleanup_algorithm": "number", - "pre_description": parent_cmd, - "post_description": packages, - "desc_limit": 72 - } - config["root"] = { - "snapshot": True - } - config.read(ini_file) - return config - - -def get_description(snapshot_type, config, section): - desc_limit = config.getint(section, "desc_limit") - if snapshot_type == "pre": - return config.get(section, "pre_description")[:desc_limit] - else: - return config.get(section, "post_description")[:desc_limit] - - -def get_pre_number(snapshot_type, prefile): - if snapshot_type == "pre": - pre_number = None - else: - try: - pre_number = prefile.read_text() - except FileNotFoundError: - raise FileNotFoundError(f"prefile {prefile} not found. Ensure you have run the pre snapshot first.") - else: - prefile.unlink() - return pre_number - - -def main(snap_pac_ini, snapper_conf_file, args): - - if os.getenv("SNAP_PAC_SKIP", "n").lower() in ["y", "yes", "true", "1"]: - return False - - parent_cmd = os.popen(f"ps -p {os.getppid()} -o args=").read().strip() - packages = " ".join([line.rstrip("\n") for line in sys.stdin]) - config = setup_config_parser(snap_pac_ini, parent_cmd, packages) - snapper_configs = get_snapper_configs(snapper_conf_file) - chroot = os.stat("/") != os.stat("/proc/1/root/.") - - for snapper_config in snapper_configs: - - if snapper_config not in config: - config.add_section(snapper_config) - - if config.getboolean(snapper_config, "snapshot"): - prefile = tempfile.gettempdir() / Path(f"snap-pac-pre_{snapper_config}") - - cleanup_algorithm = config.get(snapper_config, "cleanup_algorithm") - description = get_description(args.type, config, snapper_config) - pre_number = get_pre_number(args.type, prefile) - - snapper_cmd = SnapperCmd(snapper_config, args.type, cleanup_algorithm, description, chroot, pre_number) - num = snapper_cmd() - logging.info(f"==> {snapper_config}: {num}") - - if args.type == "pre": - prefile.write_text(num) - - return True - - -if __name__ == "__main__": - - snap_pac_ini = Path("/etc/snap-pac.ini") - snapper_conf_file = Path("/etc/conf.d/snapper") - - parser = ArgumentParser(description="Script for taking pre/post snapper snapshots. Used with pacman hooks.") - parser.add_argument(dest="type", choices=["pre", "post"]) - args = parser.parse_args() - - main(snap_pac_ini, snapper_conf_file, args) diff --git a/tests/test_script.py b/tests/test_script.py deleted file mode 100644 index a629e0f..0000000 --- a/tests/test_script.py +++ /dev/null @@ -1,106 +0,0 @@ -from configparser import ConfigParser -import tempfile -from pathlib import Path -import os - -import pytest - -from scripts.snap_pac import ( - SnapperCmd, get_pre_number, get_snapper_configs, main, setup_config_parser, - get_description -) - - -@pytest.fixture -def config(): - config = ConfigParser() - config["DEFAULT"] = { - "snapshot": False, - "cleanup_algorithm": "number", - "pre_description": "foo", - "post_description": "bar", - "desc_limit": 72 - } - config["root"] = { - "snapshot": True - } - config["home"] = { - "snapshot": True, - "desc_limit": 3, - "post_description": "a really long description" - } - return config - - -@pytest.fixture -def prefile(): - with tempfile.NamedTemporaryFile("w", delete=False) as f: - f.write("1234") - name = f.name - return Path(name) - - -@pytest.mark.parametrize("snapper_cmd, actual_cmd", [ - ( - SnapperCmd("root", "pre", "number", "foo"), - "snapper --config root create --type pre --cleanup-algorithm number --print-number --description \"foo\"" - ), - ( - SnapperCmd("root", "post", "number", "bar", False, 1234), - "snapper --config root create --type post --cleanup-algorithm number --print-number" - " --description \"bar\" --pre-number 1234" - ), - ( - SnapperCmd("root", "post", "number", "bar", True, 1234), - "snapper --no-dbus --config root create --type post --cleanup-algorithm number --print-number" - " --description \"bar\" --pre-number 1234" - ) -]) -def test_snapper_cmd(snapper_cmd, actual_cmd): - assert str(snapper_cmd) == actual_cmd - - -def test_get_snapper_configs(): - with tempfile.NamedTemporaryFile("w", delete=False) as f: - f.write("## Path: System/Snapper\n") - f.write("\n") - f.write("## Type: string\n") - f.write("## Default: \"\"\n") - f.write("# List of snapper configurations.\n") - f.write("SNAPPER_CONFIGS=\"home root foo bar\"\n") - name = f.name - assert get_snapper_configs(Path(name)) == ["home", "root", "foo", "bar"] - - -def test_skip_snap_pac(): - os.environ["SNAP_PAC_SKIP"] = "y" - assert main("foo", "bar", "yep") is False - - -def test_setup_config_parser(config): - with tempfile.NamedTemporaryFile("w", delete=False) as f: - f.write("[home]\n") - f.write("snapshot = True\n") - f.write("desc_limit = 3\n") - f.write("post_description = a really long description\n") - name = f.name - config2 = setup_config_parser(name, "foo", "bar") - assert config == config2 - - -def test_get_pre_number_pre(prefile): - assert get_pre_number("pre", prefile) is None - - -def test_get_pre_number_post(prefile): - assert get_pre_number("post", prefile) == "1234" - - -def test_no_prefile(): - with pytest.raises(FileNotFoundError): - get_pre_number("post", Path("/tmp/foo-pre-file-not-found")) - - -@pytest.mark.parametrize("snapshot_type, description", [("pre", "foo"), ("post", "a r")]) -def test_get_description(snapshot_type, description, config): - assert get_description(snapshot_type, config, "home") == description