Add options for important=yes userdata

Check if user-specified packages and user-specified commands are in
important lists and if so add userdata important=yes

Fixes #38.
This commit is contained in:
Wes Barnett 2021-03-13 07:08:40 -05:00
parent 796b0f790d
commit 287c1eacac
No known key found for this signature in database
GPG key ID: 1070BCC98C18BD66
3 changed files with 62 additions and 7 deletions

View file

@ -2,6 +2,7 @@
# Each section corresponds with a snapper configuration. Add additional sections to add # 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. # other configurations to be snapshotted. By default, only the root configuration is snapshotted.
# Create a setion named [DEFAULT] to have a setting apply for all snapper configurations
[root] [root]
# How many characters to limit the description for snapper. # How many characters to limit the description for snapper.
@ -19,6 +20,13 @@ cleanup_algorithm = number
# Post snapshot description. Default is the list of packages involved in the pacman transaction # Post snapshot description. Default is the list of packages involved in the pacman transaction
#post_description = pacman post snapshot #post_description = pacman post snapshot
# Uncomment to add "important=yes" to userdata for snapshots referring to these packages
#important_packages = ["linux"]
# Uncomment to add "important=yes" to userdata for snapshots that were created with the
#following commands
#important_commands = ["pacman -Syu"]
# Example for another snapper configuration named "home" # Example for another snapper configuration named "home"
# [home] # [home]
# snapshot = True # snapshot = True

View file

@ -18,6 +18,7 @@
from argparse import ArgumentParser from argparse import ArgumentParser
from configparser import ConfigParser from configparser import ConfigParser
import json
import logging import logging
from pathlib import Path from pathlib import Path
import os import os
@ -30,7 +31,8 @@ logging.basicConfig(format="%(message)s", level=logging.INFO)
class SnapperCmd: class SnapperCmd:
def __init__(self, config, snapshot_type, cleanup_algorithm, description="", nodbus=False, pre_number=None): def __init__(self, config, snapshot_type, cleanup_algorithm, description="",
nodbus=False, pre_number=None, important=False):
self.cmd = ["snapper"] self.cmd = ["snapper"]
if nodbus: if nodbus:
self.cmd.append("--no-dbus") self.cmd.append("--no-dbus")
@ -40,6 +42,8 @@ class SnapperCmd:
self.cmd.append("--print-number") self.cmd.append("--print-number")
if description: if description:
self.cmd.append(f"--description \"{description}\"") self.cmd.append(f"--description \"{description}\"")
if important:
self.cmd.append("--userdata \"important=yes\"")
if snapshot_type == "post": if snapshot_type == "post":
if pre_number is not None: if pre_number is not None:
self.cmd.append(f"--pre-number {pre_number}") self.cmd.append(f"--pre-number {pre_number}")
@ -69,7 +73,7 @@ def setup_config_parser(ini_file, parent_cmd, packages):
"snapshot": False, "snapshot": False,
"cleanup_algorithm": "number", "cleanup_algorithm": "number",
"pre_description": parent_cmd, "pre_description": parent_cmd,
"post_description": packages, "post_description": " ".join(packages),
"desc_limit": 72 "desc_limit": 72
} }
config["root"] = { config["root"] = {
@ -100,13 +104,25 @@ def get_pre_number(snapshot_type, prefile):
return pre_number return pre_number
def check_important_commands(config, snapper_config, parent_cmd):
important_commands = json.loads(config.get(snapper_config, "important_commands"))
return parent_cmd in important_commands
def check_important_packages(config, snapper_config, packages):
important_packages = json.loads(config.get(snapper_config, "important_packages"))
print(important_packages)
print(packages)
return any(x in important_packages for x in packages)
def main(snap_pac_ini, snapper_conf_file, args): def main(snap_pac_ini, snapper_conf_file, args):
if os.getenv("SNAP_PAC_SKIP", "n").lower() in ["y", "yes", "true", "1"]: if os.getenv("SNAP_PAC_SKIP", "n").lower() in ["y", "yes", "true", "1"]:
return False return False
parent_cmd = os.popen(f"ps -p {os.getppid()} -o args=").read().strip() parent_cmd = os.popen(f"ps -p {os.getppid()} -o args=").read().strip()
packages = " ".join([line.rstrip("\n") for line in sys.stdin]) packages = [line.rstrip("\n") for line in sys.stdin]
config = setup_config_parser(snap_pac_ini, parent_cmd, packages) config = setup_config_parser(snap_pac_ini, parent_cmd, packages)
snapper_configs = get_snapper_configs(snapper_conf_file) snapper_configs = get_snapper_configs(snapper_conf_file)
chroot = os.stat("/") != os.stat("/proc/1/root/.") chroot = os.stat("/") != os.stat("/proc/1/root/.")
@ -123,7 +139,11 @@ def main(snap_pac_ini, snapper_conf_file, args):
description = get_description(args.type, config, snapper_config) description = get_description(args.type, config, snapper_config)
pre_number = get_pre_number(args.type, prefile) pre_number = get_pre_number(args.type, prefile)
snapper_cmd = SnapperCmd(snapper_config, args.type, cleanup_algorithm, description, chroot, pre_number) important = (check_important_commands(config, snapper_config, parent_cmd) or
check_important_packages(config, snapper_config, packages))
snapper_cmd = SnapperCmd(snapper_config, args.type, cleanup_algorithm,
description, chroot, pre_number, important)
num = snapper_cmd() num = snapper_cmd()
logging.info(f"==> {snapper_config}: {num}") logging.info(f"==> {snapper_config}: {num}")

View file

@ -6,8 +6,8 @@ import os
import pytest import pytest
from scripts.snap_pac import ( from scripts.snap_pac import (
SnapperCmd, get_pre_number, get_snapper_configs, main, setup_config_parser, SnapperCmd, check_important_commands, check_important_packages, get_pre_number, get_snapper_configs,
get_description main, setup_config_parser, get_description
) )
@ -54,6 +54,11 @@ def prefile():
SnapperCmd("root", "post", "number", "bar", True, 1234), SnapperCmd("root", "post", "number", "bar", True, 1234),
"snapper --no-dbus --config root create --type post --cleanup-algorithm number --print-number" "snapper --no-dbus --config root create --type post --cleanup-algorithm number --print-number"
" --description \"bar\" --pre-number 1234" " --description \"bar\" --pre-number 1234"
),
(
SnapperCmd("root", "post", "number", "bar", False, 1234, True),
"snapper --config root create --type post --cleanup-algorithm number --print-number"
" --description \"bar\" --userdata \"important=yes\" --pre-number 1234"
) )
]) ])
def test_snapper_cmd(snapper_cmd, actual_cmd): def test_snapper_cmd(snapper_cmd, actual_cmd):
@ -84,7 +89,7 @@ def test_setup_config_parser(config):
f.write("desc_limit = 3\n") f.write("desc_limit = 3\n")
f.write("post_description = a really long description\n") f.write("post_description = a really long description\n")
name = f.name name = f.name
config2 = setup_config_parser(name, "foo", "bar") config2 = setup_config_parser(name, "foo", ["bar"])
assert config == config2 assert config == config2
@ -104,3 +109,25 @@ def test_no_prefile():
@pytest.mark.parametrize("snapshot_type, description", [("pre", "foo"), ("post", "a r")]) @pytest.mark.parametrize("snapshot_type, description", [("pre", "foo"), ("post", "a r")])
def test_get_description(snapshot_type, description, config): def test_get_description(snapshot_type, description, config):
assert get_description(snapshot_type, config, "home") == description assert get_description(snapshot_type, config, "home") == description
def test_important_commands():
parent_cmd = "pacman -Syu"
with tempfile.NamedTemporaryFile("w", delete=False) as f:
f.write("[DEFAULT]\n")
f.write("important_commands = [\"pacman -Syu\"]\n")
name = f.name
config = setup_config_parser(name, parent_cmd, ["bar"])
important = check_important_commands(config, "root", parent_cmd)
assert important
def test_important_packages():
packages = ["bar", "linux", "vim"]
with tempfile.NamedTemporaryFile("w", delete=False) as f:
f.write("[DEFAULT]\n")
f.write("important_packages = [\"linux\"]\n")
name = f.name
config = setup_config_parser(name, "pacman -S", packages)
important = check_important_packages(config, "root", packages)
assert important