Compare commits
No commits in common. "main" and "0.8.1" have entirely different histories.
25 changed files with 479 additions and 987 deletions
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -1,24 +0,0 @@
|
||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
|
|
@ -1,20 +0,0 @@
|
||||||
---
|
|
||||||
name: Feature request
|
|
||||||
about: Suggest an idea for this project
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
|
||||||
|
|
||||||
**Describe the solution you'd like**
|
|
||||||
A clear and concise description of what you want to happen.
|
|
||||||
|
|
||||||
**Describe alternatives you've considered**
|
|
||||||
A clear and concise description of any alternative solutions or features you've considered.
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context or screenshots about the feature request here.
|
|
||||||
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
3
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
- [ ] Closes #xxxx
|
|
||||||
- [ ] Tests added / passed
|
|
||||||
- [ ] All linting tests pass
|
|
||||||
28
.github/workflows/docs.yml
vendored
28
.github/workflows/docs.yml
vendored
|
|
@ -1,28 +0,0 @@
|
||||||
name: Docs
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install Python
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.9
|
|
||||||
- name: Install dependencies
|
|
||||||
run: python -m pip install --upgrade pip sphinx
|
|
||||||
- name: Build docs
|
|
||||||
run: sphinx-build -a docs/source docs/build
|
|
||||||
- name: Deploy
|
|
||||||
uses: peaceiris/actions-gh-pages@v3
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
publish_dir: ./docs/build
|
|
||||||
publish_branch: gh-pages
|
|
||||||
24
.github/workflows/tests.yml
vendored
24
.github/workflows/tests.yml
vendored
|
|
@ -1,24 +0,0 @@
|
||||||
name: Tests
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Install Python
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: 3.9
|
|
||||||
- name: Install dependencies
|
|
||||||
run: python -m pip install --upgrade pip pytest flake8
|
|
||||||
- name: Run linter
|
|
||||||
run: flake8 --max-line-length=120 scripts/
|
|
||||||
- name: Run tests
|
|
||||||
run: python -m pytest -v
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -1,4 +0,0 @@
|
||||||
__pycache__
|
|
||||||
venv
|
|
||||||
docs/build
|
|
||||||
man8
|
|
||||||
26
Makefile
26
Makefile
|
|
@ -1,6 +1,6 @@
|
||||||
# snap-pac
|
# snap-pac
|
||||||
# https://github.com/wesbarnett/snap-pac
|
# https://github.com/wesbarnett/snap-pac
|
||||||
# Copyright (C) 2016-2021 James W. Barnett
|
# Copyright (C) 2016 James W. Barnett
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -20,23 +20,9 @@ PREFIX ?= /usr
|
||||||
|
|
||||||
SHARE_DIR = $(DESTDIR)$(PREFIX)/share
|
SHARE_DIR = $(DESTDIR)$(PREFIX)/share
|
||||||
|
|
||||||
.PHONY: install test docs
|
.PHONY: install
|
||||||
|
|
||||||
install: man
|
install:
|
||||||
@install -Dm755 scripts/snap_pac.py $(SHARE_DIR)/libalpm/scripts/snap-pac
|
@install -Dm755 scripts/* -t $(SHARE_DIR)/libalpm/scripts/
|
||||||
@install -Dm644 hooks/* -t $(SHARE_DIR)/libalpm/hooks/
|
@install -Dm644 hooks/* -t $(SHARE_DIR)/libalpm/hooks/
|
||||||
@install -Dm644 LICENSE -t $(SHARE_DIR)/licenses/$(PKGNAME)/
|
@install -Dm644 LICENSE -t $(SHARE_DIR)/licenses/$(PKGNAME)
|
||||||
@install -Dm644 man8/* -t $(SHARE_DIR)/man/man8/
|
|
||||||
@install -Dm644 README.md -t $(SHARE_DIR)/doc/$(PKGNAME)/
|
|
||||||
@install -Dm644 extra/snap-pac.ini $(DESTDIR)/etc/snap-pac.ini
|
|
||||||
|
|
||||||
test:
|
|
||||||
@python -m pytest -v .
|
|
||||||
|
|
||||||
man:
|
|
||||||
@cd docs && make man
|
|
||||||
@mkdir -p man8
|
|
||||||
@awk 'NR==33{print ".SH DESCRIPTION"}7' docs/build/man/snap-pac.8 > man8/snap-pac.8
|
|
||||||
|
|
||||||
docs: man
|
|
||||||
@sphinx-build -a docs/source docs/build
|
|
||||||
|
|
|
||||||
248
README.md
248
README.md
|
|
@ -1,25 +1,253 @@
|
||||||
# snap-pac
|
# snap-pac
|
||||||
|
|
||||||
## Synopsis
|
[](https://aur.archlinux.org/packages/snap-pac/)
|
||||||
|
[](https://github.com/wesbarnett/snap-pac/blob/master/LICENSE)
|
||||||
|
[](https://aur.archlinux.org/packages/snap-pac/)
|
||||||
|
|
||||||
This is a set of [pacman](https://wiki.archlinux.org/index.php/Pacman) hooks and scripts that automatically cause [snapper](http://snapper.io/) to perform a snapshot before pacman transactions.
|
This causes Arch Linux's pacman to use
|
||||||
|
[snapper](https://wiki.archlinux.org/index.php/Snapper) to automatically take a
|
||||||
|
pre and post snapshot before and after pacman transactions using pacman's hooks
|
||||||
|
feature, similar to how YaST does with OpenSuse. This provides a simple way to
|
||||||
|
undo changes to a system after a pacman transaction.
|
||||||
|
|
||||||
Forked from Wes Barnett's solution for my own personal needs. Takes a single screenshot vs. the original's pre/post pair.
|
* [Installation](#installation)
|
||||||
|
* [Configuration](#configuration)
|
||||||
|
* [Usage](#usage)
|
||||||
|
* [Example](#example)
|
||||||
|
* [Troubleshooting](#troubleshooting)
|
||||||
|
* [License](#license)
|
||||||
|
* [FAQ](#faq)
|
||||||
|
* [See also](#see-also)
|
||||||
|
* [Did you like this project?](#did-you-like-this-project)
|
||||||
|
|
||||||
## [Installation](https://wesbarnett.github.io/snap-pac/installation.html)
|
## Installation
|
||||||
|
|
||||||
|
Install [the package from the
|
||||||
|
AUR](https://aur.archlinux.org/packages/snap-pac/).
|
||||||
|
|
||||||
|
### PGP Key
|
||||||
|
|
||||||
|
I have signed the release tarball with my PGP key. You must import my public key
|
||||||
|
to verify the signature if you are using the PKGBUILD in the AUR. This can be
|
||||||
|
done via:
|
||||||
|
|
||||||
|
$ gpg --keyserver hkp://pgp.mit.edu --recv-keys 0xE4B5E45AA3B8C5C3
|
||||||
|
|
||||||
|
The key's fingerprint is `8535CEF3F3C38EE69555BF67E4B5E45AA3B8C5C3`.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
Most likely, configuration is not needed. By default, the snapper configuration named `root` will have snapshots taken before every pacman transaction.
|
Configuration is done via the snapper configuration files, with extra variables
|
||||||
|
specific to these pacman hooks. The defaults should be suitable for most users,
|
||||||
|
so you shouldn't need to change anything.
|
||||||
|
|
||||||
For more information on configuring snap-pac, see [the documentation](https://wesbarnett.github.io/snap-pac/configuration.html).
|
The following are possible settings you can place in each snapper configuration
|
||||||
|
file (*e.g.*, `/etc/snapper/configs/root`, etc.):
|
||||||
|
|
||||||
## Documentation
|
* `PACMAN_PRE_POST` - perform pacman pre/post snapshots for this configuration.
|
||||||
|
Default is `"no"` for all configurations, except for the `root` configuration
|
||||||
|
which is `"yes"`.
|
||||||
|
* `PACMAN_CLEANUP_ALGORITHM` - snapper algorithm used in cleaning up the pacman pre/post
|
||||||
|
snapshots. Default is `"number"`.
|
||||||
|
* `PACMAN_PRE_DESCRIPTION` - snapper description used for the pacman pre snapshot.
|
||||||
|
Default is the pacman command that called the snapshot.
|
||||||
|
* `PACMAN_POST_DESCRIPTION` - snapper description used for the pacman post snapshot.
|
||||||
|
Default is the pacman command that called the snapshot.
|
||||||
|
|
||||||
See the [documentation here](https://wesbarnett.github.io/snap-pac/) or `man 8 snap-pac` after installation.
|
The following setting can be changed in the snapper configuration file
|
||||||
|
`/etc/conf.d/snapper`:
|
||||||
|
|
||||||
|
* `PACMAN_ABORT_ON_FAIL` - By default this is set to `"no"`. When set to `"yes"`
|
||||||
|
this causes pacman to abort a transaction if the snap-pac pre hook fails. This
|
||||||
|
prevents an upgrade/installation/removal from occurring if a pre snapshot cannot be
|
||||||
|
performed.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Taking snapshots
|
||||||
|
|
||||||
|
**Use pacman—and AUR helpers—as normal and watch snapper do its thing.** No
|
||||||
|
bash scripts for you to call. No bash aliases to setup.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Undoing a transaction
|
||||||
|
|
||||||
|
To undo changes from a pacman transaction, use `snapper undochange`. See the
|
||||||
|
snapper manpage and the following example.
|
||||||
|
|
||||||
|
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 `/`. 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.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Installing the `nano` package as normal:
|
||||||
|
|
||||||
|
# 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...
|
||||||
|
home N/A
|
||||||
|
root 1033 ✓
|
||||||
|
:: Processing package changes...
|
||||||
|
(1/1) installing nano [######################################] 100%
|
||||||
|
:: Running post-transaction hooks...
|
||||||
|
(1/1) Performing snapper post snapshots...
|
||||||
|
home N/A
|
||||||
|
root 1034 ✓
|
||||||
|
|
||||||
|
The snapper snapshot number is given for each snapper configuration that is
|
||||||
|
used (tip: this is also logged in pacman's log). "N/A" means that configuration
|
||||||
|
is not set up for snap-pac (see above).
|
||||||
|
|
||||||
|
And here are the snapshots:
|
||||||
|
|
||||||
|
# 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 |
|
||||||
|
|
||||||
|
What changed?
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
|
||||||
|
I truncated the above output, but it continues. See the manpage for snapper to
|
||||||
|
see what each symbol means. You can also do `snapper diff` in the same
|
||||||
|
way—I'll spare you that one.
|
||||||
|
|
||||||
|
To undo the upgrade:
|
||||||
|
|
||||||
|
# snapper -c root undochange 1033..1034
|
||||||
|
create:0 modify:3 delete:100
|
||||||
|
|
||||||
|
And `nano` is now gone, along with all the files it changed:
|
||||||
|
|
||||||
|
$ pacman -Qi nano
|
||||||
|
error: package 'nano' was not found
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
After reviewing the documentation, [check the issues page] and file a new issue if your problem is not covered.
|
**==> ERROR: One or more PGP signatures could not be verified!**
|
||||||
|
|
||||||
|
See [PGP Key](#pgp-key) on how to import my PGP key.
|
||||||
|
|
||||||
|
**ERROR: /etc/conf.d/snapper does not exist!**
|
||||||
|
|
||||||
|
*snap-pac* reads in the snapper configurations from `/etc/conf.d/snapper`. It
|
||||||
|
can't do that if the file doesn't exist. I'm not sure what you've done to not
|
||||||
|
have it exist in the default location.
|
||||||
|
|
||||||
|
**WARNING: No snapper configurations found, so not taking any snapshots!**
|
||||||
|
|
||||||
|
No snapper configurations were found in `/etc/conf.d/snapper`. This means you
|
||||||
|
haven't created any configurations yet using `snapper create-config`. See the
|
||||||
|
snapper manpage on how to do this.
|
||||||
|
|
||||||
|
**WARNING: No snapper configurations are set up for snapshots to be taken!**
|
||||||
|
|
||||||
|
Although you seem to have created at least one snapper configuration, none of
|
||||||
|
them 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
|
||||||
|
`PACMAN_PRE_POST` set to `yes` in its configuration file. This message means you
|
||||||
|
don't have a snapper configuration named `root` (or `PACMAN_PRE_POST` is set to
|
||||||
|
`no` for it) and no other configuration is set up for snapshots. See the
|
||||||
|
configuration section above.
|
||||||
|
|
||||||
|
**WARNING: *prefile* does not exist, so no post snapshot will be taken. If you are initially installing snap-pac, this is normal.**
|
||||||
|
|
||||||
|
*snap-pac* saves the pre snapshot's number in a temporary file. Somehow it got
|
||||||
|
removed before the post snapshot could be taken. When you initially install
|
||||||
|
*snap-pac* the post hook is run, but the pre hook never was, so this message
|
||||||
|
will show up then as well and is safe to ignore in that circumstance.
|
||||||
|
|
||||||
|
**ERROR: Unable to use snapper without dbus. Are you in a chroot environment?**
|
||||||
|
|
||||||
|
Snapper requires dbus. If you chroot into another environment, dbus will not be
|
||||||
|
available, so snapper can't take snapshots.
|
||||||
|
|
||||||
|
**"N/A" next to one of the snapper configurations in the hook's output**
|
||||||
|
|
||||||
|
*snap-pac* lists all snapper configurations it finds and tells you which ones it
|
||||||
|
took a snapshot of along with the snapshot number. "N/A" means the configuration
|
||||||
|
is not set up for snap-pac, so no snapshot was taken for that snapper
|
||||||
|
configuration. See [configuration](#configuration).
|
||||||
|
|
||||||
|
**Other problems**
|
||||||
|
|
||||||
|
If you have a problem not listed here, check the [open
|
||||||
|
issues](https://github.com/wesbarnett/snap-pac/issues) and file new issue if
|
||||||
|
your problem is not listed.
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
**Does snap-pac backup non-btrfs `/boot` partitions?**
|
||||||
|
|
||||||
|
Nope. See
|
||||||
|
[here](https://github.com/wesbarnett/snap-pac/issues/7#issuecomment-245593818)
|
||||||
|
for an example on how to set this up.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
snap-pac
|
||||||
|
|
||||||
|
Copyright (C) 2016 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.
|
||||||
|
|
||||||
|
## See also
|
||||||
|
|
||||||
|
* [ArchWiki Btrfs article](https://wiki.archlinux.org/index.php/Btrfs)
|
||||||
|
* [ArchWiki Snapper article](https://wiki.archlinux.org/index.php/Snapper)
|
||||||
|
* [Btrfs homepage](https://wiki.archlinux.org/index.php/Btrfs)
|
||||||
|
* [snapper homepage](http://snapper.io/)
|
||||||
|
* `man alpm-hooks`
|
||||||
|
* `man btrfs`
|
||||||
|
* `man snapper`
|
||||||
|
|
||||||
|
## Did you like this project?
|
||||||
|
|
||||||
|
If you like this project, send me a Bitcoin tip: `1PZziQoUJfhMKZC8gXQZtS5ebHWMba3Geb`
|
||||||
|
|
||||||
[check the issues page]: https://codeberg.org/ak95/snap-pac/issues
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
# Minimal makefile for Sphinx documentation
|
|
||||||
#
|
|
||||||
|
|
||||||
# You can set these variables from the command line, and also
|
|
||||||
# from the environment for the first two.
|
|
||||||
SPHINXOPTS ?=
|
|
||||||
SPHINXBUILD ?= sphinx-build
|
|
||||||
SOURCEDIR = source
|
|
||||||
BUILDDIR = build
|
|
||||||
|
|
||||||
# Put it first so that "make" without argument is like "make help".
|
|
||||||
help:
|
|
||||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
||||||
|
|
||||||
.PHONY: help Makefile
|
|
||||||
|
|
||||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
||||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
||||||
%: Makefile
|
|
||||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
@ECHO OFF
|
|
||||||
|
|
||||||
pushd %~dp0
|
|
||||||
|
|
||||||
REM Command file for Sphinx documentation
|
|
||||||
|
|
||||||
if "%SPHINXBUILD%" == "" (
|
|
||||||
set SPHINXBUILD=sphinx-build
|
|
||||||
)
|
|
||||||
set SOURCEDIR=source
|
|
||||||
set BUILDDIR=build
|
|
||||||
|
|
||||||
if "%1" == "" goto help
|
|
||||||
|
|
||||||
%SPHINXBUILD% >NUL 2>NUL
|
|
||||||
if errorlevel 9009 (
|
|
||||||
echo.
|
|
||||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
|
||||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
|
||||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
|
||||||
echo.may add the Sphinx directory to PATH.
|
|
||||||
echo.
|
|
||||||
echo.If you don't have Sphinx installed, grab it from
|
|
||||||
echo.http://sphinx-doc.org/
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
goto end
|
|
||||||
|
|
||||||
:help
|
|
||||||
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
|
||||||
|
|
||||||
:end
|
|
||||||
popd
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
# Configuration file for the Sphinx documentation builder.
|
|
||||||
#
|
|
||||||
# This file only contains a selection of the most common options. For a full
|
|
||||||
# list see the documentation:
|
|
||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
||||||
|
|
||||||
# -- Path setup --------------------------------------------------------------
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#
|
|
||||||
# import os
|
|
||||||
# import sys
|
|
||||||
# sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
|
|
||||||
# -- Project information -----------------------------------------------------
|
|
||||||
|
|
||||||
project = 'snap-pac'
|
|
||||||
copyright = '2021, Wes Barnett, PhD'
|
|
||||||
author = 'Wes Barnett, PhD'
|
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = [
|
|
||||||
]
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
# This pattern also affects html_static_path and html_extra_path.
|
|
||||||
exclude_patterns = []
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output -------------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
#
|
|
||||||
html_theme = 'alabaster'
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
html_theme_options = {
|
|
||||||
'badge_branch': 'main',
|
|
||||||
'description': 'pacman hooks that use snapper to create pre/post btrfs snapshots',
|
|
||||||
'fixed_sidebar': True,
|
|
||||||
'github_banner': True,
|
|
||||||
'github_user': 'wesbarnett',
|
|
||||||
'github_repo': 'snap-pac',
|
|
||||||
'github_type': 'star'
|
|
||||||
}
|
|
||||||
|
|
||||||
man_pages = [("index", "snap-pac", "Pacman hooks that use snapper to create pre/post btrfs snapshots like openSUSE's YaST", "Wes Barnett", "8")]
|
|
||||||
manpages_url = 'https://man.archlinux.org/man/{page}.{section}'
|
|
||||||
|
|
@ -1,99 +0,0 @@
|
||||||
Configuration
|
|
||||||
=============
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
Configuration is done via Python ini configuration files. The defaults
|
|
||||||
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 ``/etc/snap-pac.ini``.
|
|
||||||
|
|
||||||
Edit with your favorite editor. The file is commented and should be
|
|
||||||
self-explanatory.
|
|
||||||
|
|
||||||
Each section corresponds with a snapper configuration. Add additional sections to add
|
|
||||||
other snapper configurations to be snapshotted. By default, only the root configuration
|
|
||||||
is snapshotted. Additionally you can add a section named ``DEFAULT`` with options that
|
|
||||||
apply to all snapper configurations unless overridden in a later section.
|
|
||||||
|
|
||||||
Each section can have the following entries:
|
|
||||||
|
|
||||||
* ``desc_limit`` - integer; maximum length of description string before being truncated.
|
|
||||||
Default: 72
|
|
||||||
* ``important_packages`` - list of strings; names of packages that if involved in a pacman
|
|
||||||
transaction will add ``important=yes`` to the snapper userdata for the pair of
|
|
||||||
snapshots. Default: []
|
|
||||||
* ``important_commands`` - list of strings; parent commands that will add
|
|
||||||
``important=yes`` to the snapper userdata for the pair of snapshots. Default: []
|
|
||||||
* ``pre_description`` - string; description for the pre snapshot. Default: the parent
|
|
||||||
command that called the pacman hook.
|
|
||||||
* ``post_description`` - string; description for the post snapshot. Default: space
|
|
||||||
separated list of packages that were installed, upgraded, or removed.
|
|
||||||
* ``snapshot`` - boolean; whether or not to snapshot the configuration. Default: True for
|
|
||||||
``root`` configuration; False otherwise.
|
|
||||||
* ``userdata`` - list of strings; key-value pairs that will be added to the userdata for
|
|
||||||
the pair of snapshots. Default: []
|
|
||||||
|
|
||||||
Examples
|
|
||||||
--------
|
|
||||||
|
|
||||||
Turn off snapshots for ``root`` configuration and turn on for ``home`` configuration:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[root]
|
|
||||||
snapshot = False
|
|
||||||
|
|
||||||
[home]
|
|
||||||
snapshot = True
|
|
||||||
|
|
||||||
|
|
||||||
Set the snapper to add the userdata ``important=yes`` for every snapshot in the ``root``
|
|
||||||
configuration when a system upgrade is performed:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[root]
|
|
||||||
important_commands = ["pacman -Syu"]
|
|
||||||
|
|
||||||
Set the snapper to add the userdata ``important=yes`` for every snapshot in the ``root``
|
|
||||||
configuration when a pacman transaction handles the packages ``linux`` and ``linux-lts``:
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[root]
|
|
||||||
important_packages = ["linux", "linux-lts"]
|
|
||||||
|
|
||||||
Here's a fuller example, with several options set for different configurations. In this
|
|
||||||
case the ``root`` configuration snapshot will have ``important=yes`` when ``linux`` and
|
|
||||||
``linux-lts`` packages are part of the transaction. Additionally when full system
|
|
||||||
upgrades are performed ``root`` snapshots will be marked ``important=yes``. Note that
|
|
||||||
you don't have to add ``snapshot = True`` for the ``root`` configuration since that is
|
|
||||||
the default.
|
|
||||||
|
|
||||||
This file also turns one snapshots for the ``home`` snapper configuration and adds the
|
|
||||||
userdata ``requestid=42,user=arthur`` to all snapshots for that configuration.
|
|
||||||
Additionally the post snapshot description is overridden.
|
|
||||||
|
|
||||||
.. code-block:: ini
|
|
||||||
|
|
||||||
[root]
|
|
||||||
important_packages = ["linux", "linux-lts"]
|
|
||||||
important_commands = ["pacman -Syu"]
|
|
||||||
|
|
||||||
[home]
|
|
||||||
snapshot = True
|
|
||||||
userdata = ["requestid=42", "user=arthur"]
|
|
||||||
post_description = "pacman transaction post snapshot"
|
|
||||||
|
|
||||||
Environment Variables
|
|
||||||
=====================
|
|
||||||
|
|
||||||
To temporarily prevent snapshots from being performed for a single pacman
|
|
||||||
command, set the environment variable ``SNAP_PAC_SKIP``. For example:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
sudo SNAP_PAC_SKIP=y pacman -Syu
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
Example
|
|
||||||
=======
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
Here is an example of how the snapshots are created and how to rollback and pacman
|
|
||||||
transaction. Here the nano package is installed:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pacman -S nano
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
snapper -c root list -t pre-post | tail -n 1
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
1033 | 1034 | Fri 22 Apr 2016 01:54:13 PM CDT | Fri 22 Apr 2016 01:54:14 PM CDT | pacman -S nano |
|
|
||||||
|
|
||||||
Here is what changed during the transaction:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
snapper -c root status 1033..1034
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
+..... /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
|
|
||||||
|
|
||||||
The above output is truncated, but it continues. See :manpage:`snapper(8)` to for what each
|
|
||||||
symbol means. You can also do ``snapper diff`` in the same way.
|
|
||||||
|
|
||||||
Then, to undo the pacman transaction:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
snapper -c root undochange 1033..1034
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
create:0 modify:3 delete:100
|
|
||||||
|
|
||||||
Now nano is no longer installed, along with all the files it changed:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pacman -Qi nano
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
error: package 'nano' was not found
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
FAQ
|
|
||||||
===
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
**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:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
Note that you will probably want to name the file with a numbered prefix less than
|
|
||||||
``05`` so that it is run before the snap-pac pre snapshot takes place. That will ensure
|
|
||||||
that the snapshot taken will have the boot partition back-up corresponding with the
|
|
||||||
state of the system. For example, you could name it ``04-backupboot.hook``.
|
|
||||||
|
|
||||||
|
|
||||||
**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:
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
[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/"
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
.. snap-pac documentation master file, created by
|
|
||||||
sphinx-quickstart on Thu Mar 11 19:49:12 2021.
|
|
||||||
You can adapt this file completely to your liking, but it should at least
|
|
||||||
contain the root `toctree` directive.
|
|
||||||
|
|
||||||
snap-pac
|
|
||||||
========
|
|
||||||
|
|
||||||
This is a set of `pacman <https://archlinux.org/pacman/>`_ hooks and script that causes
|
|
||||||
`snapper <http://snapper.io/>`_ to automatically take a pre and post snapshot before and
|
|
||||||
after pacman transactions, similar to how `YaST <https://yast.opensuse.org/>`_ 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.
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
:caption: When you run pacman, the snapper pre/post snapshots are created automatically. For a fuller example see :doc:`examples`.
|
|
||||||
:emphasize-lines: 17,18,25,26
|
|
||||||
|
|
||||||
$ 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
|
|
||||||
|
|
||||||
|
|
||||||
To undo changes from a pacman transaction, use ``snapper undochange``. See the :manpage:`snapper(8)`
|
|
||||||
for more details as well as examples.
|
|
||||||
|
|
||||||
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 /. 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.
|
|
||||||
|
|
||||||
Note that the pre transaction hooks occur before the pacman transaction but after the
|
|
||||||
pacman database is synced, if applicable. In other words, if you run `pacman -Syu` and
|
|
||||||
roll back the upgrade according to the above instructions, you will not have rolled back
|
|
||||||
the pacman database to the previous state. Thus, if, after upgrading and rolling back
|
|
||||||
the upgrade, you then install a package, it will possibly be a partial upgrade, which is
|
|
||||||
unsupported.
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 1
|
|
||||||
|
|
||||||
installation
|
|
||||||
configuration
|
|
||||||
examples
|
|
||||||
troubleshooting
|
|
||||||
faq
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
Install the ``snap-pac`` package using pacman:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
pacman -S snap-pac
|
|
||||||
|
|
||||||
Alternatively download the `latest release and signature
|
|
||||||
<https://github.com/wesbarnett/snap-pac/releases>`_. Then, verify the download:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
gpg --verify snap-pac-<version>.tar.gz.sig
|
|
||||||
|
|
||||||
where ``<version>`` is the version number you downloaded.
|
|
||||||
|
|
||||||
Finally, run:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
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``.
|
|
||||||
|
|
||||||
Dependencies
|
|
||||||
------------
|
|
||||||
|
|
||||||
``python``, ``pacman``, and ``snapper`` are all required.
|
|
||||||
|
|
||||||
Testing
|
|
||||||
-------
|
|
||||||
|
|
||||||
For testing, ``pytest`` is required. To run the tests do:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
make test
|
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Typically, you will not need to build the documentation on your own and can simply
|
|
||||||
access it by visiting the `online documentation
|
|
||||||
<https://wesbarnett.github.io/snap-pac/>`_ or by accessing the manpage:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
man 8 snap-pac
|
|
||||||
|
|
||||||
To build the documentation, ``sphinx`` is required. To build the documentation you can
|
|
||||||
do:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
make docs
|
|
||||||
|
|
||||||
The resulting html documentation will then be located at ``docs/build/index.html``.
|
|
||||||
Additionally, this generates the manpage which will be located under ``man8``.
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
Troubleshooting
|
|
||||||
===============
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
**snap-pac is only taking snapshots of the root configuration.**
|
|
||||||
|
|
||||||
That's the default behavior. See :doc:`configuration`.
|
|
||||||
|
|
||||||
**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 :doc:`configuration`.
|
|
||||||
|
|
||||||
**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 snapper diff, snapper status, snapper undochange, etc. See the Filters
|
|
||||||
section in :manpage:`snapper(8)` for more information.
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
# snap-pac example configuration file
|
|
||||||
# see snap-pac(8) for more details
|
|
||||||
|
|
||||||
# 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.
|
|
||||||
# Create a section named [DEFAULT] to have a setting apply for all snapper configurations
|
|
||||||
|
|
||||||
## Uncomment to set parameters for snapper configuration named root
|
|
||||||
#[root]
|
|
||||||
|
|
||||||
## How many characters to limit the description for snapper.
|
|
||||||
## Default is 72
|
|
||||||
#desc_limit = 72
|
|
||||||
|
|
||||||
## Whether or not to take snapshots of this snapper configuration
|
|
||||||
## Default is True for root configuration and False for all other configurations
|
|
||||||
#snapshot = True
|
|
||||||
|
|
||||||
## What snapper cleanup algorithm to use
|
|
||||||
## Default is number
|
|
||||||
#cleanup_algorithm = number
|
|
||||||
|
|
||||||
## Uncomment to add "important=yes" to userdata for snapshots referring to these packages
|
|
||||||
## Default is []
|
|
||||||
#important_packages = ["linux", "linux-lts"]
|
|
||||||
|
|
||||||
## Uncomment to add "important=yes" to userdata for snapshots that were created with the following commands
|
|
||||||
## Default is []
|
|
||||||
#important_commands = ["pacman -Syu"]
|
|
||||||
|
|
||||||
## Add custom userdata. Each key-value pair should be an item in the list
|
|
||||||
## Default is []
|
|
||||||
#userdata = ["key=value","foo=bar"]
|
|
||||||
|
|
||||||
## Example for another snapper configuration named "home"
|
|
||||||
# [home]
|
|
||||||
## Default is False
|
|
||||||
# snapshot = True
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# snap-pac
|
# snap-pac
|
||||||
# https://github.com/wesbarnett/snap-pac
|
# https://github.com/wesbarnett/snap-pac
|
||||||
# Copyright (C) 2016, 2017, 2018 James W. Barnett
|
# Copyright (C) 2016 James W. Barnett
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -24,9 +24,8 @@ Type = Package
|
||||||
Target = *
|
Target = *
|
||||||
|
|
||||||
[Action]
|
[Action]
|
||||||
Description = Taking snapper snapshot before installing...
|
Description = Performing snapper pre snapshots...
|
||||||
Depends = snap-pac
|
Depends = snap-pac
|
||||||
When = PreTransaction
|
When = PreTransaction
|
||||||
Exec = /usr/share/libalpm/scripts/snap-pac
|
Exec = /usr/share/libalpm/scripts/snap-pac pre
|
||||||
NeedsTargets
|
AbortOnFail
|
||||||
AbortOnFail
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# snap-pac
|
# snap-pac
|
||||||
# https://github.com/wesbarnett/snap-pac
|
# https://github.com/wesbarnett/snap-pac
|
||||||
# Copyright (C) 2016, 2017, 2018 James W. Barnett
|
# Copyright (C) 2016 James W. Barnett
|
||||||
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -22,7 +22,7 @@ Type = Package
|
||||||
Target = snap-pac
|
Target = snap-pac
|
||||||
|
|
||||||
[Action]
|
[Action]
|
||||||
Description = You are removing snap-pac. No post transaction snapshots will be taken.
|
Description = NOTE: You are removing snap-pac. No post transaction snapshots will be taken.
|
||||||
Depends = snap-pac
|
Depends = snap-pac
|
||||||
When = PreTransaction
|
When = PreTransaction
|
||||||
Exec = /usr/bin/bash -c "rm -f /tmp/snap-pac-pre_*"
|
Exec = /usr/share/libalpm/scripts/snap-pac-remove
|
||||||
30
hooks/zz_snapper-post.hook
Normal file
30
hooks/zz_snapper-post.hook
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# snap-pac
|
||||||
|
# https://github.com/wesbarnett/snap-pac
|
||||||
|
# Copyright (C) 2016 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...
|
||||||
|
Depends = snap-pac
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/share/libalpm/scripts/snap-pac post
|
||||||
149
scripts/snap-pac
Executable file
149
scripts/snap-pac
Executable file
|
|
@ -0,0 +1,149 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# snap-pac
|
||||||
|
# https://github.com/wesbarnett/snap-pac
|
||||||
|
# Copyright (C) 2016 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.
|
||||||
|
|
||||||
|
# Main script.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SNAPPER_CONFIG_FILE=/etc/conf.d/snapper
|
||||||
|
|
||||||
|
ERRORMSG=" \033[00;31mERROR:\033[00m"
|
||||||
|
WARNINGMSG=" \033[00;33mWARNING:\033[00m"
|
||||||
|
|
||||||
|
PACMAN_ABORT_ON_FAIL="no"
|
||||||
|
|
||||||
|
# Virtual console fonts don't have the unicode checkmark
|
||||||
|
if [[ "$TERM" == "linux" ]]; then
|
||||||
|
checkmark="done"
|
||||||
|
else
|
||||||
|
checkmark="✓"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$SNAPPER_CONFIG_FILE" ]]; then
|
||||||
|
source "$SNAPPER_CONFIG_FILE"
|
||||||
|
else
|
||||||
|
echo -e "$ERRORMSG $SNAPPER_CONFIG_FILE does not exist!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo -e "$ERRORMSG Script must be run as root."
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -d /var/run/dbus ]]; then
|
||||||
|
echo -e "$ERRORMSG Unable to use snapper without dbus. Are you in a chroot environment?"
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $# -ne 1 ]]; then
|
||||||
|
echo -e "$ERRORMSG Only one argument should be passed to this script."
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $1 != "pre" ]] && [[ $1 != "post" ]]; then
|
||||||
|
echo -e "$ERRORMSG First argument should either be 'pre' or 'post'."
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$SNAPPER_CONFIGS" ]]; then
|
||||||
|
echo -e "$ERRORMSG No snapper configurations found, so not taking any snapshots!"
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
declare -r pre_or_post=$1
|
||||||
|
declare pacman_cmd
|
||||||
|
pacman_cmd="$(sed 's./usr/bin/pacman.pacman.g' <(ps -C pacman -o args=))"
|
||||||
|
|
||||||
|
declare -i x=0
|
||||||
|
for CONFIG in $SNAPPER_CONFIGS; do
|
||||||
|
|
||||||
|
# Set defaults
|
||||||
|
PACMAN_PRE_POST="no"
|
||||||
|
if [[ $CONFIG == "root" ]]; then
|
||||||
|
PACMAN_PRE_POST="yes"
|
||||||
|
fi
|
||||||
|
PACMAN_PRE_DESCRIPTION="$pacman_cmd"
|
||||||
|
PACMAN_POST_DESCRIPTION="$pacman_cmd"
|
||||||
|
PACMAN_CLEANUP_ALGORITHM="number"
|
||||||
|
|
||||||
|
# Source snapper configuration to override defaults
|
||||||
|
source /etc/snapper/configs/"$CONFIG"
|
||||||
|
|
||||||
|
echo -n " $CONFIG "
|
||||||
|
|
||||||
|
if [[ $PACMAN_PRE_POST == "yes" ]]; then
|
||||||
|
|
||||||
|
prefile="/tmp/snap-pac-pre_$CONFIG"
|
||||||
|
snapper_cmd="snapper --config $CONFIG create --type $pre_or_post --cleanup-algorithm $PACMAN_CLEANUP_ALGORITHM"
|
||||||
|
|
||||||
|
x=$((x+1))
|
||||||
|
|
||||||
|
if [[ "$pre_or_post" == "pre" ]]; then
|
||||||
|
$snapper_cmd --description "$PACMAN_PRE_DESCRIPTION" --print-number > "$prefile"
|
||||||
|
echo -n "$(< "$prefile") "
|
||||||
|
echo "$checkmark"
|
||||||
|
elif [[ -f $prefile ]]; then
|
||||||
|
postnum=$($snapper_cmd --description "$PACMAN_POST_DESCRIPTION" --print-number --pre-number "$(< "$prefile")")
|
||||||
|
echo -n "$postnum "
|
||||||
|
echo "$checkmark"
|
||||||
|
rm "$prefile"
|
||||||
|
else
|
||||||
|
echo -e "$WARNINGMSG $prefile does not exist, so no post snapshot will be taken. If you are initially installing snap-pac, this is normal."
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
echo "N/A"
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $x -eq 0 ]]; then
|
||||||
|
echo -e "$ERRORMSG No snapper configurations are set up for snapshots to be taken!"
|
||||||
|
if [[ $PACMAN_ABORT_ON_FAIL == "yes" ]]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 0
|
||||||
49
scripts/snap-pac-remove
Executable file
49
scripts/snap-pac-remove
Executable file
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# snap-pac
|
||||||
|
# https://github.com/wesbarnett/snap-pac
|
||||||
|
# Copyright (C) 2016 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.
|
||||||
|
|
||||||
|
# Removes file that stores pre number when snap-pac is removed.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SNAPPER_CONFIG_FILE=/etc/conf.d/snapper
|
||||||
|
|
||||||
|
ERRORMSG="\033[00;31mERROR:\033[00m"
|
||||||
|
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo -e "$ERRORMSG Script must be run as root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$SNAPPER_CONFIG_FILE" ]]; then
|
||||||
|
source "$SNAPPER_CONFIG_FILE"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for CONFIG in $SNAPPER_CONFIGS; do
|
||||||
|
|
||||||
|
prefile="/tmp/snap-pac-pre_$CONFIG"
|
||||||
|
if [[ -f "$prefile" ]]; then
|
||||||
|
rm "$prefile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
||||||
|
|
@ -1,161 +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 snapshots; run from pacman hooks."""
|
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
|
||||||
from configparser import ConfigParser
|
|
||||||
import json
|
|
||||||
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, cleanup_algorithm, description="", nodbus=False, userdata=""):
|
|
||||||
self.cmd = ["snapper"]
|
|
||||||
if nodbus:
|
|
||||||
self.cmd.append("--no-dbus")
|
|
||||||
self.cmd.extend([
|
|
||||||
f"--config {config} create",
|
|
||||||
f"--cleanup-algorithm {cleanup_algorithm}",
|
|
||||||
"--print-number"
|
|
||||||
])
|
|
||||||
self.cmd.append("--read-write")
|
|
||||||
if description:
|
|
||||||
self.cmd.append(f"--description \"{description}\"")
|
|
||||||
if userdata:
|
|
||||||
self.cmd.append(f"--userdata \"{userdata}\"")
|
|
||||||
|
|
||||||
def __call__(self):
|
|
||||||
return os.popen(self.__str__()).read().rstrip("\n")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return " ".join(self.cmd)
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigProcessor:
|
|
||||||
|
|
||||||
def __init__(self, ini_file, parent_cmd=None, packages=None):
|
|
||||||
"""Set up defaults for snap-pac configuration."""
|
|
||||||
|
|
||||||
if parent_cmd is None:
|
|
||||||
self.parent_cmd = os.popen(f"ps -p {os.getppid()} -o args=").read().strip()
|
|
||||||
else:
|
|
||||||
self.parent_cmd = parent_cmd
|
|
||||||
|
|
||||||
if packages is None:
|
|
||||||
self.packages = [line.rstrip("\n") for line in sys.stdin]
|
|
||||||
else:
|
|
||||||
self.packages = packages
|
|
||||||
|
|
||||||
self.config = ConfigParser()
|
|
||||||
self.config["DEFAULT"] = {
|
|
||||||
"snapshot": False,
|
|
||||||
"cleanup_algorithm": "number",
|
|
||||||
"description": self.parent_cmd,
|
|
||||||
"desc_limit": 72,
|
|
||||||
"important_packages": [],
|
|
||||||
"important_commands": [],
|
|
||||||
"userdata": []
|
|
||||||
}
|
|
||||||
self.config["root"] = {
|
|
||||||
"snapshot": True
|
|
||||||
}
|
|
||||||
self.config.read(ini_file)
|
|
||||||
|
|
||||||
def get_cleanup_algorithm(self, section):
|
|
||||||
return self.config.get(section, "cleanup_algorithm")
|
|
||||||
|
|
||||||
def get_description(self, section):
|
|
||||||
desc_limit = self.config.getint(section, "desc_limit")
|
|
||||||
return self.config.get(section, "description")[:desc_limit]
|
|
||||||
|
|
||||||
def check_important_commands(self, section):
|
|
||||||
return self.parent_cmd in json.loads(self.config.get(section, "important_commands"))
|
|
||||||
|
|
||||||
def check_important_packages(self, section):
|
|
||||||
important_packages = json.loads(self.config.get(section, "important_packages"))
|
|
||||||
return any(x in important_packages for x in self.packages)
|
|
||||||
|
|
||||||
def check_important(self, section):
|
|
||||||
return (self.check_important_commands(section) or
|
|
||||||
self.check_important_packages(section))
|
|
||||||
|
|
||||||
def get_userdata(self, section):
|
|
||||||
userdata = set(json.loads(self.config.get(section, "userdata")))
|
|
||||||
if self.check_important(section):
|
|
||||||
userdata.add("important=yes")
|
|
||||||
return ",".join(sorted(list(userdata)))
|
|
||||||
|
|
||||||
def __call__(self, section):
|
|
||||||
if section not in self.config:
|
|
||||||
self.config.add_section(section)
|
|
||||||
return {
|
|
||||||
"description": self.get_description(section),
|
|
||||||
"cleanup_algorithm": self.get_cleanup_algorithm(section),
|
|
||||||
"userdata": self.get_userdata(section),
|
|
||||||
"snapshot": self.config.getboolean(section, "snapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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 check_skip():
|
|
||||||
return os.getenv("SNAP_PAC_SKIP", "n").lower() in ["y", "yes", "true", "1"]
|
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
|
||||||
parser = ArgumentParser(description="Script for taking snapper snapshots. Used with pacman hooks.")
|
|
||||||
parser.add_argument(
|
|
||||||
"--ini", dest="snap_pac_ini", type=Path,
|
|
||||||
default=Path("/etc/snap-pac.ini"), help="snap-pac ini file path"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--conf", dest="snapper_conf_file", type=Path,
|
|
||||||
default=Path("/etc/conf.d/snapper"), help="snapper configuration file path"
|
|
||||||
)
|
|
||||||
return parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
if check_skip():
|
|
||||||
logging.warning("snapper snapshots skipped")
|
|
||||||
quit()
|
|
||||||
|
|
||||||
args = parse_args()
|
|
||||||
config_processor = ConfigProcessor(args.snap_pac_ini)
|
|
||||||
chroot = os.stat("/") != os.stat("/proc/1/root/.")
|
|
||||||
|
|
||||||
for snapper_config in get_snapper_configs(args.snapper_conf_file):
|
|
||||||
|
|
||||||
data = config_processor(snapper_config)
|
|
||||||
if data["snapshot"]:
|
|
||||||
num = SnapperCmd(snapper_config, data["cleanup_algorithm"], data["description"], chroot, data["userdata"])()
|
|
||||||
logging.info(f"==> {snapper_config}: {num}")
|
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
import tempfile
|
|
||||||
from pathlib import Path
|
|
||||||
import os
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from scripts.snap_pac import check_skip, ConfigProcessor, get_snapper_configs, Prefile, SnapperCmd
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("snapper_cmd, actual_cmd", [
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "pre", "number", "foo"),
|
|
||||||
"snapper --config root create --cleanup-algorithm number --print-number --description \"foo\" --type pre"
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "post", "number", "bar", False, 1234),
|
|
||||||
"snapper --config root create --cleanup-algorithm number --print-number"
|
|
||||||
" --description \"bar\" --pre-number 1234 --type post"
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "post", "number", "bar", True, 1234),
|
|
||||||
"snapper --no-dbus --config root create --cleanup-algorithm number --print-number"
|
|
||||||
" --description \"bar\" --pre-number 1234 --type post"
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "post", "number", "bar", False, 1234, "important=yes"),
|
|
||||||
"snapper --config root create --cleanup-algorithm number --print-number"
|
|
||||||
" --description \"bar\" --userdata \"important=yes\" --pre-number 1234 --type post"
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "post", "number", "bar", False, 1234, "foo=bar,important=yes"),
|
|
||||||
"snapper --config root create --cleanup-algorithm number --print-number"
|
|
||||||
" --description \"bar\" --userdata \"foo=bar,important=yes\" --pre-number 1234 --type post"
|
|
||||||
),
|
|
||||||
(
|
|
||||||
SnapperCmd("root", "post", "number", "bar", False, None, "foo=bar,important=yes"),
|
|
||||||
"snapper --config root create --cleanup-algorithm number --print-number"
|
|
||||||
" --description \"bar\" --userdata \"foo=bar,important=yes\" --type single"
|
|
||||||
)
|
|
||||||
])
|
|
||||||
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 check_skip() is True
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("section, command, packages, snapshot_type, result", [
|
|
||||||
(
|
|
||||||
"root", "foo", ["bar"], "pre",
|
|
||||||
{"description": "foo", "cleanup_algorithm": "number", "userdata": "", "snapshot": True}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"root", "pacman -Syu", [], "pre",
|
|
||||||
{"description": "pacman -Syu", "cleanup_algorithm": "number", "userdata": "important=yes", "snapshot": True}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"mail", "pacman -Syu", [], "pre",
|
|
||||||
{"description": "pacman -Syu", "cleanup_algorithm": "number", "userdata": "", "snapshot": False}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"home", "pacman -Syu", [], "pre",
|
|
||||||
{"description": "pac", "cleanup_algorithm": "number", "userdata": "foo=bar,requestid=42", "snapshot": True}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"home", "pacman -Syu", [], "post",
|
|
||||||
{"description": "a r", "cleanup_algorithm": "number", "userdata": "foo=bar,requestid=42", "snapshot": True}
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"myconfig", "pacman -S linux", ["linux"], "post",
|
|
||||||
{"description": "linux", "cleanup_algorithm": "timeline",
|
|
||||||
"userdata": "foo=bar,important=yes,requestid=42", "snapshot": True}
|
|
||||||
),
|
|
||||||
])
|
|
||||||
def test_config_processor(section, command, packages, snapshot_type, result):
|
|
||||||
with tempfile.NamedTemporaryFile("w", delete=False) as f:
|
|
||||||
f.write("[root]\n")
|
|
||||||
f.write("important_commands = [\"pacman -Syu\"]\n\n")
|
|
||||||
f.write("[home]\n")
|
|
||||||
f.write("snapshot = True\n")
|
|
||||||
f.write("desc_limit = 3\n")
|
|
||||||
f.write("post_description = a really long description\n")
|
|
||||||
f.write("userdata = [\"foo=bar\", \"requestid=42\"]\n\n")
|
|
||||||
f.write("[myconfig]\n")
|
|
||||||
f.write("snapshot = True\n")
|
|
||||||
f.write("cleanup_algorithm = timeline\n")
|
|
||||||
f.write("important_packages = [\"linux\", \"linux-lts\"]\n")
|
|
||||||
f.write("userdata = [\"foo=bar\", \"requestid=42\"]\n")
|
|
||||||
name = f.name
|
|
||||||
config_processor = ConfigProcessor(name, snapshot_type, command, packages)
|
|
||||||
assert config_processor(section) == result
|
|
||||||
|
|
||||||
|
|
||||||
def test_prefile_read_none():
|
|
||||||
prefile = Prefile("root", "pre")
|
|
||||||
assert prefile.read() is None
|
|
||||||
|
|
||||||
|
|
||||||
def test_prefile_read():
|
|
||||||
prefile = Prefile("root", "pre")
|
|
||||||
prefile.write("1234")
|
|
||||||
prefile = Prefile("root", "post")
|
|
||||||
assert prefile.read() == "1234"
|
|
||||||
|
|
||||||
|
|
||||||
def test_no_prefile():
|
|
||||||
prefile = Prefile("foo-pre-file-not-found", "post")
|
|
||||||
assert prefile.read() is None
|
|
||||||
Loading…
Add table
Reference in a new issue